| 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 writeselect * 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.comMr Dayal |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2008-06-25 : 03:22:11
|
yes, MS SQL Server does not support that syntaxuse INNER JOIN insteadSELECT 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] |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-06-25 : 03:23:38
|
Use EXISTS.Try thisSELECT st.*FROM SomeTable AS stWHERE 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" |
 |
|
|
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] |
 |
|
|
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 #SampleSELECT 1, 1 UNION ALLSELECT 1, 2 UNION ALLSELECT 2, 9 UNION ALLSELECT 2, 8 UNION ALLSELECT 3, 0-- Peso 1SELECT s.*FROM #Sample AS sWHERE EXISTS (SELECT * FROM #Sample AS w GROUP BY w.i HAVING w.i = s.i AND MIN(w.j) = s.j)-- Peso 2SELECT s.*FROM #Sample AS sWHERE EXISTS (SELECT * FROM #Sample AS w WHERE w.i = s.i GROUP BY w.i HAVING MIN(w.j) = s.j)-- Khtan 1SELECT s.* FROM #Sample AS sINNER 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 2SELECT s.* FROM #Sample AS sINNER JOIN ( SELECT i, MIN(j) AS j FROM #Sample GROUP BY i ) AS w ON w.i = s.iWHERE w.j = s.jDROP TABLE #Sample E 12°55'05.25"N 56°04'39.16" |
 |
|
|
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] |
 |
|
|
mr_dayal
Starting Member
37 Posts |
Posted - 2008-06-25 : 03:38:15
|
quote: Originally posted by Peso Use EXISTS.Try thisSELECT st.*FROM SomeTable AS stWHERE 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 |
 |
|
|
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 dataINSERT #SampleSELECT v1.Number, v2.NumberFROM master..spt_values AS v1INNER 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" |
 |
|
|
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 |
 |
|
|
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 queryMr Dayal |
 |
|
|
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 dataINSERT #SampleSELECT v1.Number, v2.NumberFROM master..spt_values AS v1INNER 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" |
 |
|
|
mr_dayal
Starting Member
37 Posts |
Posted - 2008-06-25 : 04:26:20
|
| r innerjoin and selfjoin the sameMr Dayal |
 |
|
|
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 sameMr Dayal
Yup. Self join means taking inner join with the same table |
 |
|
|
mr_dayal
Starting Member
37 Posts |
Posted - 2008-06-25 : 05:45:23
|
| souupse I have a table billreturn having following databill_no item_id rem_qty0608/1 JC/SER/SAL/KN/CHUR0001 10608/1 JC/SER/SAL/KM/PATI0001 10608/1 JC/HL/KUR/KN/FORM0001 10608/2 JC/HC/WH/KN/PICT0002 100608/6 JC/HC/WH/KN/PICT0001 100608/6 JC/HC/WH/KN/PICT0002 20608/6 JC/HC/WH/KN/PICT0001 90608/6 JC/HC/WH/KN/PICT0001 40608/6 JC/HC/WH/KN/PICT0001 00608/7 JC/HC/WH/KN/PICT0001 100608/7 JC/HC/WH/KN/PICT0001 90608/7 JC/HC/WH/KN/PICT0001 80608/7 JC/HC/WH/KN/PICT0001 70608/7 JC/HC/WH/KN/PICT0001 60608/7 JC/HC/WH/KN/PICT0001 50608/10 JC/HC/CLO/KM/CLOC0002 10608/11 JC/HC/CLO/KM/CLOC0001 10608/12 JC/HC/WH/KN/PICT0002 100608/12 JC/HL/KUR/KN/FORM0001 20608/12 JC/SER/SAL/KN/CHUR0001 1Now I want to retrive all the records group by bill_no and items having minimum rem_qty for a particular Bill_no. Mr Dayal |
 |
|
|
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_qtysuppose I want to filter only one group (bill_no)In above query where will I pass where clause "where item_id=something"Mr Dayal |
 |
|
|
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 databill_no item_id rem_qty0608/1 JC/SER/SAL/KN/CHUR0001 10608/1 JC/SER/SAL/KM/PATI0001 10608/1 JC/HL/KUR/KN/FORM0001 10608/2 JC/HC/WH/KN/PICT0002 100608/6 JC/HC/WH/KN/PICT0001 100608/6 JC/HC/WH/KN/PICT0002 20608/6 JC/HC/WH/KN/PICT0001 90608/6 JC/HC/WH/KN/PICT0001 40608/6 JC/HC/WH/KN/PICT0001 00608/7 JC/HC/WH/KN/PICT0001 100608/7 JC/HC/WH/KN/PICT0001 90608/7 JC/HC/WH/KN/PICT0001 80608/7 JC/HC/WH/KN/PICT0001 70608/7 JC/HC/WH/KN/PICT0001 60608/7 JC/HC/WH/KN/PICT0001 50608/10 JC/HC/CLO/KM/CLOC0002 10608/11 JC/HC/CLO/KM/CLOC0001 10608/12 JC/HC/WH/KN/PICT0002 100608/12 JC/HL/KUR/KN/FORM0001 20608/12 JC/SER/SAL/KN/CHUR0001 1Now 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_qtyFROM YourTable tINNER JOIN (SELECT bill_no,MIN(rem_qty) AS minqty FROM YourTable GROUP BY bill_no) t1ON t1.bill_no=t.bill_noAND t1.minqty=t.rem_qty Also suggest you to open new thread for asking new questions. |
 |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2008-06-25 : 10:21:14
|
quote: Originally posted by Peso Use EXISTS.Try thisSELECT st.*FROM SomeTable AS stWHERE 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 MadhivananFailing to plan is Planning to fail |
 |
|
|
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 |
 |
|
|
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" |
 |
|
|
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 expressionSELECT (100*2.5+6/7.0)SELECT 'test'SELECT GETDATE()MadhivananFailing to plan is Planning to fail |
 |
|
|
mr_dayal
Starting Member
37 Posts |
Posted - 2008-06-27 : 09:43:37
|
| yes yes,, thanks it workedMr Dayal |
 |
|
|
Next Page
|