Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Sub Queries

Author  Topic 

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 03:18:32
Hi,
How Will I retrieve values from multiple colums while using subqueries in sql server 2005.

Suppose I write

select * from sometable where (item_id,rem_qty) in (select item_id,min(rem_qty) from somtable group by item_id)

It works in case of Oracle ,but not in sql server..



Any one Help me ...
mail me on shankar@horionsoftech.com

Mr Dayal

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2008-06-25 : 03:22:11
yes, MS SQL Server does not support that syntax

use INNER JOIN instead

SELECT  t.* 
FROM sometable t
INNER JOIN
(
SELECT item_id, rem_qty = MIN(rem_qty)
FROM sometable
GROUP BY item_id
) m ON t.item_id = m.item_id
AND t.rem_qty = m.rem_qty




KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 03:23:38
Use EXISTS.

Try this
SELECT	st.*
FROM SomeTable AS st
WHERE EXISTS (SELECT * FROM SomTable AS x GROUP BY x.Item_ID HAVING x.ItemID = st.Item_ID AND MIN(x.Rem_Qty) = st.Rem_Qty)


It is not as efficient as the other suggestion, but maybe you are more familiar with the syntax.


E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2008-06-25 : 03:27:36
interesting .. . never thought of doing it this way


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 03:34:04
Run this sample script twice; first as is, and second time with the CREATE INDEX statement uncommented.
Turn on "Include Actual Execution Plan".

Without index, EXISTS is twice as efficient as INNER JOIN according to execution plan.
With index, EXISTS is exactly equal to INNER JOIN according to execution plan.

But SQL Profiler reveals that INNER JOIN is most efficient in both cases.
CREATE TABLE	#Sample
(
i INT,
j INT
)

--CREATE CLUSTERED INDEX IX_Sample ON #Sample (i, j)

INSERT #Sample
SELECT 1, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 2, 9 UNION ALL
SELECT 2, 8 UNION ALL
SELECT 3, 0

-- Peso 1
SELECT s.*
FROM #Sample AS s
WHERE EXISTS (SELECT * FROM #Sample AS w GROUP BY w.i HAVING w.i = s.i AND MIN(w.j) = s.j)

-- Peso 2
SELECT s.*
FROM #Sample AS s
WHERE EXISTS (SELECT * FROM #Sample AS w WHERE w.i = s.i GROUP BY w.i HAVING MIN(w.j) = s.j)

-- Khtan 1
SELECT s.*
FROM #Sample AS s
INNER JOIN (
SELECT i,
MIN(j) AS j
FROM #Sample
GROUP BY i
) AS w ON w.i = s.i
AND w.j = s.j

-- Khtan 2
SELECT s.*
FROM #Sample AS s
INNER JOIN (
SELECT i,
MIN(j) AS j
FROM #Sample
GROUP BY i
) AS w ON w.i = s.i
WHERE w.j = s.j

DROP TABLE #Sample



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2008-06-25 : 03:36:36
Thanks Peter. Was wondering about any performance difference


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 03:38:15
quote:
Originally posted by Peso

Use EXISTS.

Try this
SELECT	st.*
FROM SomeTable AS st
WHERE EXISTS (SELECT * FROM SomTable AS x GROUP BY x.Item_ID HAVING x.ItemID = st.Item_ID AND MIN(x.Rem_Qty) = st.Rem_Qty)


It is not as efficient as the other suggestion, but maybe you are more familiar with the syntax.


E 12°55'05.25"
N 56°04'39.16"






It works Thanks.....

Mr Dayal
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 03:41:23
Now redo the test twice (with/without index) with this sample data
INSERT		#Sample
SELECT v1.Number,
v2.Number
FROM master..spt_values AS v1
INNER JOIN master..spt_values AS v2 ON v2.Type = 'p'
WHERE v1.Type = 'p'
AND v1.Number BETWEEN 0 AND 99
AND v2.Number BETWEEN 0 AND 99



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 03:45:32
Thanks a lot both of u KHtan and peso.



Both queries run perfactally.

Mr Dayal
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 03:47:34
But As far as I know Using HAVING Clause Slows down the performance a bit..is't it..
So I would preffer KH 's query


Mr Dayal
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 03:47:53
Now redo the test twice (with/without index) with this sample data
INSERT		#Sample
SELECT v1.Number,
v2.Number
FROM master..spt_values AS v1
INNER JOIN master..spt_values AS v2 ON v2.Type = 'p'
WHERE v1.Type = 'p'
AND v1.Number BETWEEN 0 AND 999
AND v2.Number BETWEEN 0 AND 999
As you now can see, the performance winner is now the EXISTS!

1a) With moderate number of samples (100x100), the absolute winners are the "2" versions with clustered index.
1b) With moderate number of samples (100x100), the absolute winners are the "1" versions with nonclustered index.
1c) With moderate number of samples (100x100), the winners are the "khtan" versions without index.

2a) With a larger number of samples (1000x1000), it's a tie for all four versions with clustered index.
2b) With a larger number of samples (1000x1000), it's a tie for all four versions with nonclustered index.
2c) With a larger number of samples (1000x1000), the winners are the "peso" versions without index.



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 04:26:20
r innerjoin and selfjoin the same

Mr Dayal
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 04:28:45
quote:
Originally posted by mr_dayal

r innerjoin and selfjoin the same

Mr Dayal


Yup. Self join means taking inner join with the same table

Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 05:45:23
souupse I have a table billreturn having following data

bill_no item_id rem_qty
0608/1 JC/SER/SAL/KN/CHUR0001 1
0608/1 JC/SER/SAL/KM/PATI0001 1
0608/1 JC/HL/KUR/KN/FORM0001 1
0608/2 JC/HC/WH/KN/PICT0002 10
0608/6 JC/HC/WH/KN/PICT0001 10
0608/6 JC/HC/WH/KN/PICT0002 2
0608/6 JC/HC/WH/KN/PICT0001 9
0608/6 JC/HC/WH/KN/PICT0001 4
0608/6 JC/HC/WH/KN/PICT0001 0
0608/7 JC/HC/WH/KN/PICT0001 10
0608/7 JC/HC/WH/KN/PICT0001 9
0608/7 JC/HC/WH/KN/PICT0001 8
0608/7 JC/HC/WH/KN/PICT0001 7
0608/7 JC/HC/WH/KN/PICT0001 6
0608/7 JC/HC/WH/KN/PICT0001 5
0608/10 JC/HC/CLO/KM/CLOC0002 1
0608/11 JC/HC/CLO/KM/CLOC0001 1
0608/12 JC/HC/WH/KN/PICT0002 10
0608/12 JC/HL/KUR/KN/FORM0001 2
0608/12 JC/SER/SAL/KN/CHUR0001 1



Now I want to retrive all the records group by bill_no and items having minimum rem_qty for a particular Bill_no.



Mr Dayal
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-25 : 05:49:37
SELECT t.*
FROM sometable t
INNER JOIN
(
SELECT item_id, rem_qty = MIN(rem_qty)
FROM sometable
GROUP BY item_id
) m ON t.item_id = m.item_id
AND t.rem_qty = m.rem_qty

suppose I want to filter only one group (bill_no)
In above query where will I pass where clause "where item_id=something"

Mr Dayal
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 05:51:35
quote:
Originally posted by mr_dayal

souupse I have a table billreturn having following data

bill_no item_id rem_qty
0608/1 JC/SER/SAL/KN/CHUR0001 1
0608/1 JC/SER/SAL/KM/PATI0001 1
0608/1 JC/HL/KUR/KN/FORM0001 1
0608/2 JC/HC/WH/KN/PICT0002 10
0608/6 JC/HC/WH/KN/PICT0001 10
0608/6 JC/HC/WH/KN/PICT0002 2
0608/6 JC/HC/WH/KN/PICT0001 9
0608/6 JC/HC/WH/KN/PICT0001 4
0608/6 JC/HC/WH/KN/PICT0001 0
0608/7 JC/HC/WH/KN/PICT0001 10
0608/7 JC/HC/WH/KN/PICT0001 9
0608/7 JC/HC/WH/KN/PICT0001 8
0608/7 JC/HC/WH/KN/PICT0001 7
0608/7 JC/HC/WH/KN/PICT0001 6
0608/7 JC/HC/WH/KN/PICT0001 5
0608/10 JC/HC/CLO/KM/CLOC0002 1
0608/11 JC/HC/CLO/KM/CLOC0001 1
0608/12 JC/HC/WH/KN/PICT0002 10
0608/12 JC/HL/KUR/KN/FORM0001 2
0608/12 JC/SER/SAL/KN/CHUR0001 1



Now I want to retrive all the records group by bill_no and items having minimum rem_qty for a particular Bill_no.



Mr Dayal


SELECT t.bill_no,t.item_id,t.rem_qty
FROM YourTable t
INNER JOIN (SELECT bill_no,MIN(rem_qty) AS minqty
FROM YourTable
GROUP BY bill_no) t1
ON t1.bill_no=t.bill_no
AND t1.minqty=t.rem_qty


Also suggest you to open new thread for asking new questions.
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2008-06-25 : 10:21:14
quote:
Originally posted by Peso

Use EXISTS.

Try this
SELECT	st.*
FROM SomeTable AS st
WHERE EXISTS (SELECT * FROM SomTable AS x GROUP BY x.Item_ID HAVING x.ItemID = st.Item_ID AND MIN(x.Rem_Qty) = st.Rem_Qty)


It is not as efficient as the other suggestion, but maybe you are more familiar with the syntax.


E 12°55'05.25"
N 56°04'39.16"



Once I used this technique and surprised that it didnt throw any error despite the usage of * againt Group by. Thats because of Exists

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-27 : 08:33:52
is there any able like DUAL used in Oracle to test arithmetic functions?


Mr Dayal
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-27 : 09:18:03
Ask at at a ORACLE forum, or at least explain what DUAL is supposed to do.



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2008-06-27 : 09:35:48
quote:
Originally posted by mr_dayal

is there any able like DUAL used in Oracle to test arithmetic functions?


Mr Dayal


You dont need to use DUAL in SQL Server Server. Just use the expression

SELECT (100*2.5+6/7.0)
SELECT 'test'
SELECT GETDATE()


Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

mr_dayal
Starting Member

37 Posts

Posted - 2008-06-27 : 09:43:37
yes yes,, thanks it worked

Mr Dayal
Go to Top of Page
    Next Page

- Advertisement -