I need to make select inside another select (sql server) - sql-server

in the select statement below I have 707 row
select detail_serial, Price from apa_invoice_detail
and I have another select statement which is
Select max(detail_serial)
,asc_item.item_name_2
,asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2
and this one gives me 197 row
I need to get the price from the first statement for the detail_serial in the second statement (for only 197 row)
I tried this:
select detail_serial, Price from apa_invoice_detail where detail_serial in
(Select max(detail_serial)
,asc_item.item_name_2
,asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2)
but it gives me "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
How can I solve this ???

try removing the columns in the inner select statement
select detail_serial, Price from apa_invoice_detail where detail_serial in
(Select max(detail_serial)
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2)

Use EXISTS instead of IN.
;WITH SecondQueryResults AS
(
Select max(detail_serial) detail_serial
, asc_item.item_name_2
, asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2
)
select
detail_serial,
Price
from
apa_invoice_detail T
where
EXISTS (SELECT 'serial exists on query result' FROM SecondQueryResults AS S WHERE S.detail_serial = T.detail_serial)
... or just select 1 column (the detail_serial) inside your IN subquery.

Related

Is null in where statement doesnt returns me rows

I am using a complex query. I need to returns me always a row even it doesnt find anything.
SELECT
a.InventoryItemID,
a.Name,
a.RetailPrice,
b.MainGroupItemCode,
b.MainGroupItemID,
c.VatValue,
a.Code,
a.Weight,
b.MainGroupItemName,
a.RetailPrice2,
a.FreePrice,
case when isnull(e.IsActive,0)=1 and isnull(d.price,0)!=0 then d.Price else RetailPrice End as CustomPrice
from InventoryMaster a
join InventoryMainGroupItems b on a.MainGroupItemID=b.MainGroupItemID
join VatCodes c on b.VatCodeID=c.VatCodeID
join InventoryPrices d on d.InventoryItemID=a.InventoryItemID
join InventoryCatalog e on e.CatalogID=d.CatalogID
where a.InventoryItemID=2 and ISNULL(e.catalogID,1)=3
The problem is in last line ISNULL(e.catalogID,1)=3. In my table it doesn't exist CatalogID with number 3.
So it doesnt returns me anything, but there is CatalogID with number 1. I have set that if is null to return me 1, Unfortunately i dont get any row back from my query. How can i fix this ?
My question has been solved i just want to add one more join table with one wheere condition isnide
SELECT *
from
(
SELECT t1.ID,
t1.Name,
COALESCE(t2.price,t1.Price) AS price ,
Row_number() OVER(partition BY t1.ID ORDER BY t1.ID) rn
FROM InventoryMaster t1
LEFT JOIN inventoryprices t2
ON t1.ID=t2.ID
LEFT join InventoryCatalog t3
ON t3.ID=t2.ID and t3.ID=2
where t1.ID=2
) t
WHERE t.rn=1
it returns me always the retailprice from First Table Inventory
Add 3 cols near beginning of the select
d.InventoryItemID,
d.CatalogID,
e.CatalogID
Then remove And ISNULL from the Where, and run to see what you get.
It may be that
join InventoryCatalog e
needs
ON d.CatalogID=ISNULL(e.catalogID,1)

Using sub-queries and filter in WHERE clause while joining tables

SELECT DISTINCT(t1.Ticker),t2.SecurityID,t2.ClosePrice,t2.QuoteDateTime FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
WHERE t2.QuoteDateTime IN (SELECT max(QuoteDateTime) FROM [Hub].[SecurityMaster].[SecurityPrices]) AND t1.SecurityTypeName = 'REIT'
I get an output with no data. The subquery doesn't run along with the other filter in the WHERE clause. I am not sure what I am doing wrong. Can somebody please help!
If you are trying to get the lastest row from SecurityPrices for each Ticker, one option is to use cross apply():
select --distinct /* distinct not needed if `Ticker` is unique on `smd`
smd.Ticker
, sp.SecurityID
, sp.ClosePrice
, sp.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityMasterDetails] as smd
cross apply (
select top 1
i.SecurityID
, i.ClosePrice
, i.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityPrices] i
where i.SecurityID = smd.SecurityID
order by i.QuoteDateTime desc
) as sp
where SecurityTypeName = 'REIT' /* which table does this column belong to? */
I think your query would be
SELECT DISTINCT TOP 1 WITH TIES
t1.Ticker,
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2 ON t2.SecurityID =t1.SecurityID
WHERE SecurityTypeName = 'REIT'
ORDER BY t2.QuoteDateTime DESC
You aren't getting results because the max(QuoteDateTime) record doesn't have SecurityTypeName = 'REIT'. I think you want the max(QuoteDateTime) for this SecurityTypeName, so this can be done with an INNER JOIN.
SELECT DISTINCT
(t1.Ticker),
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
INNER JOIN
(SELECT max(QuoteDateTime) DT FROM [Hub].[SecurityMaster].[SecurityPrices]) P on P.DT = t2.QuoteDateTime
WHERE SecurityTypeName = 'REIT'
EDIT
Your data doesn't have what you think it does, I suspect. Here is how you can check...
--Find the SecurityID that matches the max date
SELECT
SecurityID ,
max(QuoteDateTime) DT
FROM [Hub].[SecurityMaster].[SecurityPrices]
GROUP BY SecurityID
--I'm betting this ID isn't in your SecurityMasterDetails where the Type is REIT
SELECT DISTINCT
SecurityID
FROM SecurityMasterDetails
WHERE SecurityTypeName = 'REIT'
Since the SecurityID returned in the first query isn't in the second query result set, you are going to get NULL results.

replace nested where condition with join

I have a SQL query that looks like this
Select a.*
From table1 a
where a.ColumnName in
(Select MAX(b.ColumnName)
from table2 b
where b.ColumnName2 in
(
Select MAX(c.columnName)
from table3 c
Group by c.ColumnName2
)
Group by b.ColumnName2
)
I am trying to write this in a join statement. I am positive inner join is what I need to get the right information. If someone could translate this to a join statement, I would be really glad.
Thank you.
EDIT 1:
I tried the typical Join statement that a rookie would.
Select a.*
from table1 a
inner join table2 b
on a.columnname = (Select max(b.columnName) from table2)
inner join table3 c
on b.columnName = (select max(c.columnName) from table3)
Obviously, that didn't work because I get 100,000+ results when I should be getting 800. I tried using an alias for table2 and table3 INSIDE the subselect statements and selecting the columnname using THAT alias like this:
Select max(bPart.columnName from table2 bPart)
Select max(cPart.columnName from table3 cPart)
Still the same result.
PERHAPS....
Though I'm not sure why a join is needed. Performance wise exists would likely be fastest, and since you're not returning values from table2 or 3 it seems like it would be the best approach.
SELECT a.*
FROM table1 a
INNER JOIN (SELECT MAX(ColumnName) MColumnName, columnname2
FROM table2
GROUP BY columnName2) B
ON A.columnName = B.mColumnName
INNER JOIN (SELECT MAX(columnName) mColumnName
FROM table3
GROUP BY ColumnName2) C
ON B.columname2 = C.MColumnName

Applying outer layer that wrapping two select statement

I have two query which has successfully inner join
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
The above query will return me the name and the corresponding number of count and the sum. I need to do a comparison between the count and sum. If the count doesnt match the sum, it will return 0, else 1. And so my idea was implementing another outer layer to wrap them up and use CASE WHEN. However, I've failed to apply an outer layer just to wrap them up? This is what I've tried:
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
)
Alright the problem can be solved by simply assigning a name to the outer layer.
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
) as whatever //SQL Server need a name to wrap
Hope it will help any newbie like me
Ok, so far you have selected everything your first select has generated (kinda useless, but a start for what you want ;) )
SELECT CASE
WHEN countresult=sumresult THEN 'Equal'
ELSE 'Not'
END
FROM ( --your join select --
)
I don't have any sample data to test this so can just go on your code.
Your queries for t1 & t2 look identical - why don't you just do a sum & count in 1 step?
SELECT COUNT(column) AS countResult
,SUM(column) AS sumResult
FROM tableA INNER JOIN tableB
ON tableA.id = tableB.id
GROUP BY name
Also, as you mention you are a newb - read up on Common Table Expressions in SQL Server.
Before SQL 2005 you had to write these convoluted queries within queries within...
Get into the habit of using CTEs now.

How to Merge SQL Query

i want the Output of the Following Query in One row
i want to merge Below SQL Query
Help me please
select Provider_ID,Circel_ID,count(distinct td_all.ID),t_det.BillNoTemp from TAPINOUT_DIFFERENCES_ALL td_all
inner join TransferDetails t_det on td_all.bill_no=t_det.Bill_No
where td_all.bill_no not in (select bill_no from TAPINOUT_DIFFERENCES_ALL where Status='Open') and sourcename='TransferDetails'
group by td_all.Provider_ID,td_all.Circel_ID,t_det.BillNoTemp
order by td_all.Provider_ID,td_all.Circel_ID
select td_all.Provider_ID,td_all.Circel_ID,TAP_DET.BillNoTemp ,count(distinct td_all.ID)as count from TAPINOUT_DIFFERENCES_ALL td_all
INNER JOIN TAPIN_Details TAP_DET ON td_all.FILENAME=TAP_DET.FLNAME
where td_all.SOURCENAME='TransferDetails' and td_all.Status='Open'
group by td_all.Provider_ID,td_all.Circel_ID,TAP_DET.BillNoTemp
order by td_all.Provider_ID,td_all.Circel_ID
select td_all.Provider_ID,td_all.Circel_ID,TAP_DET.BillNoTemp,count(distinct td_all.ID)AS COUNT from TAPINOUT_DIFFERENCES_ALL td_all
inner join TAPIN_Details TAP_DET on td_all.FILENAME=TAP_DET.FLNAME
where td_all.anb_comments='Invoice Not Found'
group by td_all.Provider_ID,td_all.Circel_ID,TAP_DET.BillNoTemp order by td_all.Provider_ID,td_all.Circel_ID
select td_all.Provider_ID,td_all.Circel_ID,t_det.BillNoTemp,count(distinct td_all.ID) from TAPINOUT_DIFFERENCES_ALL td_all
inner join TransferDetails t_det on td_all.bill_no=t_det.Bill_No
where td_all.anb_comments='IT File not found'
group by td_all.Provider_ID,td_all.Circel_ID,t_det.BillNoTemp order by td_all.Provider_ID,td_all.Circel_ID
I think you're looking for the UNION operator, which lets you append the results of multiple queries into a single result set.
It works like so:
SELECT columns FROM tbl1 WHERE criteria
UNION
SELECT columns FROM tbl2 WHERE criteria
Use UNION keyword between statements.
SELECT bla, bla2 FROM table1
UNION ALL
SELECT bla3, bla4 FROM table2

Resources