So I have a situation which can be referred to the table below:
TABLE A TABLE B TABLE C
ID TOTAL_PRICE ORDER_ID ID ID ORDER ID
1 10 101 101 1001 101
2 20 101 103 1002 101
3 25 103 1003 103
4 10 103 1004 103
With all these tables I'm expecting of this result:
EXPECTED OUTPUT
ID TOTAL_PRICE ORDER_ID ID
1 10 101 1001
2 20 101 1002
3 25 103 1003
4 10 103 1004
And the result that I get follows:
REAL OUTPUT
ID TOTAL_PRICE ORDER_ID ID
1 10 101 1001
1 10 101 1002
2 20 101 1001
2 20 101 1002
3 25 103 1003
3 25 103 1004
4 10 103 1003
4 10 103 1004
My sql as follows and I'm using SQL Oracle:
SELECT a.id, a.total_price, a.order.id, c.id
FROM a,b,c
WHERE a.order_id=b.id AND b.id=c.order_id
With that situation, how can I solve the problem in order to get the expected output? Thank you.
It seems that you want to assign one id from table c for each row from table a given your matching tables criteria. For this you could use row_number to enumerate your rows inside tables a and c and then assign this information with the row number respectively:
select
a.id, a.total_price, a.order_id, c.id
from (select *, row_number over (partition by order_id order by id) as rn from a) a
join b on a.order_id = b.id
join (select id, order_id, row_number over (partition by order_id order by id) as rn from c) on b.id = c.order_id
where a.rn = c.rn
Related
I just want to get the result which displays the reference which is not tallied in sum of table2. when i run my query below it will give me an wrong sum which it gets doubled even if group by cusid ,refno.
Table 1
RefNo
CusID
TotalAmount
1
1001
50
2
1001
30
3
1002
40
Table 2
RefNo
CusID
Particular
Amount
1
1001
Paper
30
1
1001
Pencil
30
2
1001
Ball
15
2
1001
Rubber
20
3
1002
Laptop
50
select * from Table1 a
INNER JOIN (Select CusID,RefNo, SUM(Amount) as CorrectTotal from Table2 group by
CusID,RefNo,
)b
ON b.CusID= a.CusID AND b.RefNo= a.RefNo
where a.TotalAmount != CorrectTotal
Expected Result
If you do it with FULL JOIN and with GROUP BY, you will also get rows where there is no record in the other table.
SELECT COALESCE(a.RefNo, b.RefNo) AS RefNo
, COALESCE(a.CusID, b.CusID) AS CusID
, a.TotalAmount
, SUM(b.Amount) AS CorrectTotal
FROM table1 a
FULL JOIN table2 b ON a.RefNo = b.RefNo
AND a.CusID = b.CusID
GROUP BY COALESCE(a.RefNo, b.RefNo)
, COALESCE(a.CusID, b.CusID)
, a.TotalAmount
ORDER BY 1, 2
Output
RefNo
CusID
TotalAmount
CorrectTotal
1
1001
50
60
2
1001
30
35
3
1002
40
50
8
888
88
(null)
9
999
(null)
99
See running demo on SQL Fiddle.
The other answer will work, but if you don't want to mess with a GROUP BY on the whole query you can also use an APPLY to do this:
SELECT a.*, c.CorrectAmount
FROM Table1 a
OUTER APPLY (
SELECT SUM(Amount) AS CorrectAmount
FROM Table2 b
WHERE b.CusID = a.CusID AND b.RefNo = a.RefNo
) c
WHERE a.TotalAmount <> c.CorrectAmount
I have scenario below. I have a table Orders(OrderId, ItemId) and i want to get all the orders where ItemId 1 and 2 is coming simulataneoudsly
OrderId ItemId
1000 1
1001 2
1002 1
1002 2
1002 3
1003 1
1003 2
1004 4
1004 5
1005 3
1006 1
1006 3
as per above table's data and the ask ....i should get output OrderId 1002 and 1003.
Use COUNT and HAVING:
SELECT OrderId
FROM Orders
WHERE
ItemId IN(1, 2)
GROUP BY OrderId
HAVING COUNT(ItemId) = 2
If duplicate ItemId is allowed in an OrderId, use:
HAVING COUNT(DISTINCT ItemId) = 2
ONLINE DEMO
Another option, using nested queries, would be:
SELECT orderId
FROM ORDERS o
WHERE o.itemId = 1
AND EXISTS (SELECT 'X'
FROM ORDERS o1
WHERE o1.orderId = o.orderId
AND o1.itemId = 2);
ONLINE DEMO
I have following data
Components
componentid title
1 houseRent
2 medical
3 Travelling Allowance
empPayrollMaster
MasterID EmployeeID SalaryMonthID
1 101 1
2 102 1
3 103 1
empPayrollDetail
DetailID MasterID ComponentID amount
1 1 1 100
2 1 2 500
3 2 1 300
4 2 3 250
5 3 1 150
6 3 2 350
7 3 3 450
Required Output
EmployeeID MasterID ComponentID amount
101 1 1 100
101 1 2 500
101 1 3 0
102 2 1 300
102 1 2 0
102 2 3 250
103 3 1 150
103 3 2 350
103 3 3 450
To get the required output if i do left outer join between components and empPayrollDetail I get null in EmployeeID and MasterID and amount Columns. How to modify left join to get the required output
You need to do a CROSS JOIN on Components and empPayrollMaster to generate first all combination of employees and components. Then, do a LEFT JOIN on empPayrollDetail to achieve the result, using ISNULL(amount, 0) for NULL amounts.
SQL Fiddle
SELECT
epm.EmployeeID,
epm.MasterID,
c.ComponentID,
amount = ISNULL(epd.amount, 0)
FROM empPayrollMaster epm
CROSS JOIN Components c
LEFT JOIN empPayrollDetail epd
ON epd.MasterID = epm.MasterID
AND epd.ComponentID = c.ComponentID
Try this
select empPayrollMaster.EmployeeID,empPayrollMaster.MasterID,
Components.componentid,isnull(empPayrollDetail.amount,0)
from empPayrollMaster
left join Components
on empPayrollMaster.EmployeeID is not null
left join empPayrollDetail
on empPayrollDetail.MasterID = empPayrollMaster.MasterID
and empPayrollDetail.ComponentID = Components.componentid
Try this way
select c.EmployeeID,d.MasterID,c.ComponentID,isnull(d.amount,0) as amount from (
select * from Components a
Cross join empPayrollMaster b) c
left outer join empPayrollDetail d on d.componentid =c.componentid
As you want the component amount for each employee in the master table you should use a insull(payrole_detail.amount,0) or, as #Turophile pointed out, the SQL standard function coalesce(payrole_detail.amount,0) for the amounts column.
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;
I am looking for a query to a result where I can see only userid1 data whose provider is not mapped in Table 2; Here is my table definition and data;
Table 1
userid providerid
1 101
1 104
1 106
1 107
2 102
2 103
2 104
Table 2
providerid
101
102
103
104
105
106
107
108
109
110
query required as per the o/p:-
userid providernotavailable
1 102
1 103
1 105
1 108
1 109
1 110
2 101
2 105
2 106
2 107
2 108
2 109
2 110
You can use the not in operator:
SELECT *
FROM table1
WHERE providerid NOT IN (SELECT providerid FROM table2)
Multiple versions: fist with NOT IN
SELECT table1.*
FROM table1
WHERE table1.providerId NOT IN ( SELECT table2.providerId FROM table2 )
Second with NOT EXISTS:
SELECT table1.*
FROM table1
WHERE NOT EXISTS ( SELECT 1
FROM table2
WHERE table1.providerId = table2.providerId )
This next one is a bit strange: we do a LEFT JOIN and we check that the second table hasn't matched:
SELECT table1.*
FROM table1
LEFT JOIN table2
ON table1.providerId = table2.providerId
WHERE table2.providerId IS NULL
Which of the three versions above performs better depends (mostly) on the cardinality of the two tables.
Sorry, I misunderstood the question. This should do the trick.
The first part of the query selects all the pairs userId - providerId. The second part removes all the ones present in table1.
SELECT U.userId, P.providerId
FROM (SELECT DISTINCT table1.userId FROM table1) U, table2 P
MINUS
SELECT table1.* FROM table1
EDIT
this is the table structure i have used to get the output
SQL> desc tab1
Name Null? Type
---------------------------- -------- ----------------
USERID NUMBER(38)
PROVIDERID NUMBER(38)
SQL> desc tab2
Name Null? Type
---------------------------- -------- ----------------
PROVIDERID NUMBER(38)
SQL> select distinct(a.userid),b.providerId from tab1 a, tab2 b
minus
select * from tab1 ;
USERID PROVIDERID
---------- ----------
1 102
1 103
1 105
1 108
1 109
1 110
2 101
2 105
2 106
2 107
2 108
2 109
2 110
13 rows selected.
SELECT a.userid, b.providerid FROM table1 a, table2 b
WHERE a.providerid IS NOT NULL
MINUS
SELECT userid, providerid FROM table1 a
WHERE a.providerid IS NOT NULL;
The query bring the desired output...
Thanks all for ur efforts.
I have a table with self referencing relation,
ID parentID UserId Title
1 null 100 A
2 1 100 B
3 2 100 C
4 2 100 D
5 null 100 E
6 5 100 F
I want to update UserId from 100 to 101 for all records with ID=1 and its children, so I want to have
ID parentID UserId Title
1 null 101 A
2 1 101 B
3 2 101 C
4 2 101 D
5 null 100 E
6 5 100 F
How can I do it in T-SQL?
You probably want to use a common table expression which allows you to generate recursive queries.
eg:
;with cte as
(
select * from yourtable where id=1
union all
select t.* from cte
inner join yourtable t on cte.id = t.parentid
)
update yourtable
set userid = 101
where id in (select id from cte)