Database:
Transaction ProductID
1 1000
2 1000
2 1001
3 1000
3 1002
4 1000
4 1001
5 1003
In the above table, how to find this result with a T-SQL statement?
+-------------+-----------+-----------------+
| PRODUCTID1 | PRODUCTID2| SUPPORT |
+-------------+-----------+-----------------+
| 1000 | 1001 | 2 |
+-------------+-----------+-----------------+
| 1000 | 1002 | 1 |
+-------------+-----------+-----------------+
| 1000 | 1003 | 0 |
+-------------+-----------+-----------------+
| 1001 | 1002 | 0 |
+-------------+-----------+-----------------+
| 1001 | 1003 | 0 |
+-------------+-----------+-----------------+
| 1002 | 1003 | 0 |,
+-------------+-----------+-----------------+
Test Table:
create table transactions(
ORDERID INT,
PRODUCTID INT
);
insert into transactions(ORDERID, PRODUCTID)
values ('1', '1000')
,('2', '1000')
,('2', '1001')
,('3', '1000')
,('3', '1002')
,('4', '1000')
,('4', '1001'),
('5', '1003');
Thanks in advance.
Can you infer the zeros? i.e. can we just say that anything not listed is zero? if so:
select t1.PRODUCTID as [PRODUCTID1], t2.PRODUCTID as [PRODUCTID2],
COUNT(1) as [SUPPORT]
from transactions t1 inner join transactions t2
on t1.ORDERID = t2.ORDERID
and t1.PRODUCTID < t2.PRODUCTID
group by t1.PRODUCTID, t2.PRODUCTID
With output:
PRODUCTID1 PRODUCTID2 SUPPORT
----------- ----------- -----------
1000 1001 2
1000 1002 1
Related
Hello everyone i have a table of inventory stock with columns as following
Item_ID | Expiry_Date | Quantity | Rate
cB0001 | 01-18-2021 | 5 | 150
cB0001 | 12-08-2020 | 3 | 145
cB0001 | 02-15-2021 | 25 | 155
Note : Rate is not an issue I just want to update the Stock Table Quantity on the basis on expiry date and available qty.
Now i want to sale inventory to customers of item cB0001 qty : 10 from the stock that expire first. Now the problem is that sale quantity is 10 and I want to minus the quantity 5 of expiry date 01-18-2021 and 3 From expiry date 12-08-2020 and 2 from 02-15-2021. Basically i want to implement FIFO logic using one query. I want to update the stock table quantity using this
update stock set quantity = quantity - '10' where item_id = 'cB0001' and expiry_Date < Now()
But this not giving accurate result. How to fix this problem? you have any idea?
I hope you understand my question
I assume you intend to do this in a trigger. So the 'trick' is to work out when the sale is fulfilled (working out IF it can be fulfilled is another issue). To do this allocate a value of 0 to rows where the cumulative quantity is less than the sale, 1 to the row where the sale can finally be fullfilled and 2 after that. I have assumed there is a unique row identifier to cope with multiple inventory entries for the same date - in my case inventory.id
drop table if exists inventory,sales;
create table inventory
(id int auto_increment primary key,Item_ID varchar(20), Expiry_Date date, Quantity int, Rate int);
create table sales (item_id varchar(20), quantity int);
insert into inventory values
( null,'cB0001' , str_to_date('01-18-2021','%m-%d-%Y'), 5 , 150),
( null,'cB0001' , str_to_date('12-08-2020','%m-%d-%Y'), 3 , 145),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 25 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0001' , str_to_date('02-15-2021','%m-%d-%Y'), 10 , 155),
( null,'cB0002' , str_to_date('02-15-2021','%m-%d-%Y'), 30 , 155);
drop trigger if exists t;
delimiter $$
create trigger t after insert on sales
for each row
begin
update inventory left join
(select s.*,
if(fst = 0, #runqty:=#runqty+quantity,#runqty:=#runqty) qty
from
(
select *,
#t:=#t+quantity cumqty,
if(#t>=#sale,if(#p>=1,2,#p:=1),#p:=0) fst
from inventory
cross join (select #t:=0,#p:=0,#sale:=new.quantity) t
where quantity > 0 and item_id = new.item_id
order by item_id,expiry_date
) s
cross join (select #runqty:=0) r
where fst in (0,1)
) a
on a.id = inventory.id
set inventory.quantity = case when fst = 0 then 0
when fst = 1 then inventory.quantity - (new.quantity - a.qty)
else inventory.quantity
end;
end $$
delimiter ;
MariaDB [sandbox]> insert into sales values('cb0001',10);
Query OK, 1 row affected (0.095 sec)
MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
| 2 | cB0001 | 2020-12-08 | 0 | 145 |
| 1 | cB0001 | 2021-01-18 | 0 | 150 |
| 3 | cB0001 | 2021-02-15 | 23 | 155 |
| 4 | cB0001 | 2021-02-15 | 10 | 155 |
| 5 | cB0001 | 2021-02-15 | 10 | 155 |
| 6 | cB0001 | 2021-02-15 | 10 | 155 |
| 7 | cB0002 | 2021-02-15 | 30 | 155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> insert into sales values('cb0001',25);
Query OK, 1 row affected (0.111 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from inventory order by item_id,expiry_date;
+----+---------+-------------+----------+------+
| id | Item_ID | Expiry_Date | Quantity | Rate |
+----+---------+-------------+----------+------+
| 2 | cB0001 | 2020-12-08 | 0 | 145 |
| 1 | cB0001 | 2021-01-18 | 0 | 150 |
| 3 | cB0001 | 2021-02-15 | 0 | 155 |
| 4 | cB0001 | 2021-02-15 | 8 | 155 |
| 5 | cB0001 | 2021-02-15 | 10 | 155 |
| 6 | cB0001 | 2021-02-15 | 10 | 155 |
| 7 | cB0002 | 2021-02-15 | 30 | 155 |
+----+---------+-------------+----------+------+
7 rows in set (0.001 sec)
I want to show data separately from income and expense table in MySQL using same query for both things but it show me when show income title date then same show expense title date. But I need to do if it find income table's 4th row and if find expense table's 2nd row, but it show me 4th row. Why?
SELECT income.date,
IF(income.income_sourch IS NULL, 'N/A', income.income_sourch )as 'Income Title',
income.amount as 'income',
IF(expense.expense_sourche IS NULL, 'N/A', expense.expense_sourche) as 'ExpenseTitle',
expense.amount as 'Expense'
from expense RIGHT JOIN income
ON expense.date=income.date
where expense.date='30-Aug-2016'
Why - because that's how joins work when you have only a date to join the 2 tables. To solve this you need to create a relationship in addition to the date bearing in mind that at any one time the number of records in income could be greater than, less than or equal to the number of records in expenses. If we generate a row number for each row in income and independently generate a row number for each row in expenses then we can join income and expenses on row number
for example
/*
CREATE TABLE INCOME (ID INT,DESCRIPTION VARCHAR(10),DT DATE,AMOUNT INT);
INSERT INTO INCOME VALUES
(1,'SALE','2016-08-30',100),
(2,'ROKY','2016-08-30',200),
(3,'KORIM','2016-08-30',300),
(4,'SALEVOUCHR','2016-08-30',400);
CREATE TABLE EXPENSES (ID INT,DESCRIPTION VARCHAR(10),DT DATE,AMOUNT INT);
TRUNCATE TABLE EXPENSES;
INSERT INTO EXPENSES VALUES
(1,'RENT','2016-08-30',100),
(2,'UTILITIES','2016-08-30',100);
/*
This code
SELECT S.DT,S.DESCRIPTION,S.AMOUNT, s.rn,T.DESCRIPTION,T.AMOUNT, t.rn1
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN:=#RN + 1 RN
FROM (SELECT #RN:=0) RN,INCOME I
) S
LEFT OUTER JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN1:=#RN1 + 1 RN1
FROM (SELECT #RN1:=0) RN1, EXPENSES E
) T ON T.RN1 = S.RN AND T.DT = S.DT
WHERE S.DT IS NOT NULL
results in
+------------+-------------+--------+------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | rn | DESCRIPTION | AMOUNT | rn1 |
+------------+-------------+--------+------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | NULL | NULL | NULL |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | NULL | NULL | NULL |
+------------+-------------+--------+------+-------------+--------+------+
BUT this is UNSAFE because it assumes that there are always more income than expense items
for example if we add 3 more expense rows
TRUNCATE TABLE EXPENSES;
INSERT INTO EXPENSES VALUES
(1,'RENT','2016-08-30',100),
(2,'UTILITIES','2016-08-30',100),
(3,'RATES','2016-08-30',100),(4,'SALARY','2016-08-30',100),(5,'INSURANCE','2016-08-30',100);
then the last expense item is lost resulting in
+------------+-------------+--------+------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | rn | DESCRIPTION | AMOUNT | rn1 |
+------------+-------------+--------+------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | RENT | 100 | 3 |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | UTILITIES | 100 | 4 |
+------------+-------------+--------+------+-------------+--------+------+
To cope with this we can simulate a full join like so
SELECT S.*,T.*
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN:=#RN + 1 RN
FROM (SELECT #RN:=0) RN,INCOME I
) S
LEFT JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN1:=#RN1 + 1 RN1
FROM (SELECT #RN1:=0) RN1, EXPENSES E
) T ON T.RN1 = S.RN AND T.DT = S.DT
UNION
SELECT S.*,T.*
FROM
(
SELECT I.DT,I.DESCRIPTION,I.AMOUNT,
#RN3:=#RN3 + 1 RN3
FROM (SELECT #RN3:=0) RN3,INCOME I
) S
RIGHT JOIN
(SELECT E.DT,E.DESCRIPTION,E.AMOUNT,
#RN4:=#RN4 + 1 RN4
FROM (SELECT #RN4:=0) RN4, EXPENSES E
) T ON T.RN4 = S.RN3 AND T.DT = S.DT
result
+------------+-------------+--------+------+------------+-------------+--------+------+
| DT | DESCRIPTION | AMOUNT | RN | DT | DESCRIPTION | AMOUNT | RN1 |
+------------+-------------+--------+------+------------+-------------+--------+------+
| 2016-08-30 | SALE | 100 | 1 | 2016-08-30 | RENT | 100 | 1 |
| 2016-08-30 | ROKY | 200 | 2 | 2016-08-30 | UTILITIES | 100 | 2 |
| 2016-08-30 | KORIM | 300 | 3 | 2016-08-30 | RATES | 100 | 3 |
| 2016-08-30 | SALEVOUCHR | 400 | 4 | 2016-08-30 | SALARY | 100 | 4 |
| NULL | NULL | NULL | NULL | 2016-08-30 | INSURANCE | 100 | 5 |
+------------+-------------+--------+------+------------+-------------+--------+------+
you just need to add limits inside the query
if expense table limit 2
if other limit 4
See how to add limit to the query with if condition
I want to select mysql column names and values and display them for each value as rows in a gridview table. Here is an illustration
+------+-------+------+-------+-------+
| id |amt1 |amt2 |amt3 |amt4 |
+------+-------+------+-------+-------+
| 1 | 300 | 500 | 460 | 780 |
+------+-------+------+-------+-------+
| 2 | 450 | 230 | 320 | 410 |
+------+-------+------+-------+-------+
| 3 | 350 | 540 | 430 | 310 |
+------+-------+------+-------+-------+
I want this mysql table to be displayed as this in the gridview table
+-------------+--------+
|particulars | amount |
+-------------+--------+
| amt1 | 300 |
+-------------+--------+
| amt2 | 500 |
+-------------+--------+
| amt3 | 460 |
+-------------+--------+
| amt4 | 780 |
+-------------+--------+
where id = 1.
Just run 2 of those queries, the first will give you column names, the second will give you the row for specific id you looking for. Once you get this data it should be pretty simple to create the table from this data using System.Data.SqlClient.SqlConnection.
columnNamesQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'YourTableName'";
dataQuery = "SELECT * FROM YourTableName WHERE id = 1";
select 'amt1' particulars, amt1 amount from t1 where id=1
union
select 'amt2' particulars, amt2 amount from t1 where id=1
union
select 'amt3' particulars, amt3 amount from t1 where id=1
union
select 'amt4' particulars, amt4 amount from t1 where id=1
I would like to update multiple colums into one column of an another table:
Table 1:
Num | ColumnA | ColumnB |
1 | Peter | Mueller |
1 | Jonny | Corleone |
2 | John | Cohn |
1 | Sarah | Wood |
Now I want to update ColumnA and ColumnB into ColumA of Table2 like this:
Table2:
Num | ColumnC |
1 | Peter, Mueller, Jonny, Corleone, Sarah, Wood |
2 | John, Cohn |
Thanks in advance
Machupicchu
Try this
INSERT INTO Table2(NUM, Columnc)
SELECT num, GROUP_CONCAT(DISTINCT CONCAT(columna,',',columnb)) name
FROM table1
group by num
Here a SQLFiddle
I want to create a table listing the comparison of each record in a table with every other record on basis of particular columns :
Example :
id | web | author | book | isbn | pub
----------------------------------------------------------------
1 | www.a.com | sam | sams book | 12345 | sams pub
2 | www.b.com | ram | rams book | 54321 | rams pub
3 | www.c.com | sam | rams book | 67891 | tams pub
4 | www.b.com | ram | gams book | 65644 | gams pub
5 | www.a.com | sam | sams book | 11111 | xyzs pub
6 | www.c.com | tam | tams book | 22222 | abcs pub
7 | www.c.com | tam | tams book | 33333 | pqrs pub
So I want to create table with the comparision result of each record with every other record
on columns web,author,book
Result Table should be : (result weight is addition of web+author+book weight)
sorceRow|destRow| web | author | book | result weight
--------------------------------------------------------
1 | 2 | 0 | 0 | 0 | 0
1 | 3 | 0 | 1 | 0 | 1
1 | 4 | 0 | 0 | 0 | 0
1 | 5 | 1 | 1 | 1 | 3
1 | 6 | 0 | 0 | 0 | 0
1 | 7 | 0 | 0 | 0 | 0
2 | 3 | 0 | 0 | 1 | 1
2 | 4 | 1 | 1 | 0 | 2
2 | 5 | 0 | 0 | 0 | 0
2 | 6 | 0 | 0 | 0 | 0
...
6 | 7 | 1 | 1 | 1 | 3
What is fastest way to get this result in SQL Server script as well as in C#?
You can do this with a non-equijoin and lots of comparisons. The following is the standard SQL method:
select t1.id as sourceRow, t2.id as destRow,
(case when t1.web = t2.web then 1 else 0 end) as Web,
(case when t1.Author = t2.Author then 1 else 0 end) as Author,
(case when t1.Book = t2.Book then 1 else 0 end) as Book,
(case when t1.ISBN = t2.ISBN then 1 else 0 end) as ISBN,
(case when t1.pub = t2.pub then 1 else 0 end) as pub
from table t1 join
table t2
on t1.id < t2.id;
Note that the comparisons would be a little more complicated if the columns could contain NULL values, but your sample data doesn't have any.
Basically CROSS JOIN of the table on itself will do that multiplication Cross Join.
As for comparison, it depends on the DB server you use - case or iif().
select
l.id as sourceRow,
r.id as destRow,
iif (r.web = l.web, 1, 0) as web,
iif (r.author = l.author, 1, 0) as author,
....
from T1 l
cross join T1 r
where l.id < r.id