IS IN (Select statement, 'value', 'value') - tsql

I am trying to run the following SQL
DELETE FROM T_ATH_POSHLD WHERE T_ATH_POSHLD.A_INSID IN (SELECT T_ATH_POSHLD.A_INSID FROM T_ATH_POSHLD LEFT JOIN T_ATH_INS ON T_ATH_POSHLD.A_INSID = T_ATH_INS.A_INSID WHERE T_ATH_INS.A_INSCLSCDE1 = 'CASH' AND T_ATH_POSHLD.A_INSID NOT IN (SELECT A_INSID FROM T_ATH_CCY) AND A_ACCID IN (SELECT A_ACCID FROM T_ATH_EXTACC, '1212OEIC', '5667033ZS'))
and in particular, am trying to check whether an ACCID is in a set of values, some coming from a table and two hardcoded. How would I achieve this?
IN (SELECT A_ACCID FROM T_ATH_EXTACC, '1212OEIC', '5667033ZS')
Doesn't work, I get an 'Incorrect Syntax error'.
Thanks

You need to use UNION to add the 2 hardcoded values to the resultset that you are passing to the in clause.
IN (SELECT A_ACCID FROM T_ATH_EXTACC UNION ALL SELECT '1212OEIC' UNION ALL SELECT '5667033ZS')

IN (SELECT '1212OEIC', '5667033ZS', A_ACCID FROM T_ATH_EXTACC )

Related

How to avoid duplicates in the STRING_AGG function

My query is below:
select
u.Id,
STRING_AGG(sf.Naziv, ', ') as 'Ustrojstvena jedinica',
ISNULL(CONVERT(varchar(200), (STRING_AGG(TRIM(p.Naziv), ', ')), 121), '')
as 'Partner',
from Ugovor as u
left join VezaUgovorPartner as vup
on vup.UgovorId = u.Id AND vup.IsDeleted = 'false'
left join [TEST_MaticniPodaci2].dbo.Partner as p
on p.PartnerID = vup.PartnerId
left join [dbo].[VezaUgovorUstrojstvenaJedinica] as vuu
on vuu.UgovorId = u.Id
left join [TEST_MaticniPodaci2].hcphs.SifZavod as sf
on sf.Id = vuu.UstrojstvenaJedinicaId
left join [dbo].[SifVrstaUgovora] as vu
on u.VrstaUgovoraId = vu.Id
group by u.Id, sf.Naziv
My problem is that I can have more sf.Naziv and also only one sf.Naziv so I have to check if there is one and then show only one result and if there is two or more to show more results. But for now the problem is when I have only one sf.Naziv, query returns two sf.Naziv with the same name because in first STRING_AGG i have more records about p.Naziv.
I have no idea how to implement DISTINCT into STRING_AGG function
Any other solutions are welcome, but I think it should work with DISTINCT function.
It looks like distinct won't work, so what you should do is put your whole query in a subquery, remove the duplicates there, then do STRING_AGG on the data that has no duplicates.
SELECT STRING_AGG(data)
FROM (
SELECT DISTINCT FROM ...
)
I like this format for distinct values:
(d is required but you can use any variable name there)
SELECT STRING_AGG(LoadNumber, ',') as LoadNumbers FROM (SELECT DISTINCT LoadNumber FROM [ASN]) d
A sample query to remove duplicates while using STRING_AGG().
WITH cte AS (
SELECT DISTINCT product
FROM activities
)
SELECT STRING_AGG(product, ',') products
FROM cte;
Or you can use the following query. The result is same -
SELECT STRING_AGG(product, ',') as products
from (
SELECT product
FROM Activities
GROUP BY product
) as _ ;

Updating a CTE table fail cause of derived or constant field

I'm using MS-SQL 2012
WITH C1
(
SELECT ID, 0 as Match, Field2, Count(*)
FROM TableX
GROUP BY ID, Fields2
)
UPDATE C1 SET Match = 1
WHERE ID = (SELECT MATCHING_ID FROM AnotherTable WHERE ID = C1.ID)
This TSQL statement gives me the following error:
Update or insert of view or function 'C1' failed because it contains a derived or constant field.
Ideally I would like to create a "fake field" named Match and set its default value to 0. Then with the update I would like to Update ONLY the records that have an existing entry on the "AnotherTable".
Any thoughts what am I doing wrong?
Thanks in advanced.
Try doing a Left Outer Join like
SELECT x.ID, ISNULL(a.Matching_ID, 0) as Match, x.Field2, Count(*)
FROM TableX x
LEFT OUTER JOIN AnotherTable a on x.ID = a.ID
GROUP BY x.ID, ISNULL(a.Matching_ID, 0), x.Fields2
without the need of a C1
If I am understanding correctly, the problem is that you are trying to update the CTE table. If you update the table directly you should be fine.
Does this modified version help?
SELECT t.ID
, CASE WHEN (EXISTS (SELECT MATCHING_ID FROM AnotherTable WHERE ID = t.ID)) THEN 1 ELSE 0 END
,t.Field2
,Count(*)
FROM TableX t
GROUP BY ID, Fields2

How to use the AS name in a query WHERE clause?

given a query like so:
SELECT
id,
(SELECT COUNT(*)
FROM members
WHERE members.network_id = networks.id) AS mem_count
FROM
networks
WHERE mem_count > 2
With this query, the where clause breaks as it does not know what mem_count is... Why can't I use the as var in the where clause?
Thanks
While bernie suggested correct answer to the question, your query can be simplified to:
SELECT
network_id as id,
count(*)
FROM
members
GROUP BY
network_id
HAVING
count(*) > 2
Which, as an additional bonus, can be faster.
You've got the concept down. You just need the right syntax. You could re-write like this and have the added benefit of making your query ANSI-compliant:
SELECT
id,
m.mem_count
FROM
networks n
JOIN (
SELECT m.network_id,
COUNT(*) AS mem_count
FROM members
GROUP BY m.network_id
) m
ON m.network_id = n.id
AND m.mem_count > 2;
Try:
SELECT
id,
(SELECT COUNT(*) as mem_count
FROM members
WHERE members.network_id = networks.id)
FROM
networks
WHERE mem_count > 2
One way would be.
Select * From (
SELECT
id,
(SELECT COUNT(*)
FROM members
WHERE members.network_id = networks.id) AS mem_count
FROM
networks)) mem_counts
WHERE mem_count > 2
A join as suggested by Bernie would be better though. Basically you confused the parser. You get the same sort of issue with group by or order by when you use AS to alias a column name.

Filter union result

I'm making select with a union.
SELECT * FROM table_1
UNION
SELECT * FROM table_2
Is it possible to filter query results by column values?
Yes, you can enclose your entire union inside another select:
select * from (
select * from table_1 union select * from table_2) as t
where t.column = 'y'
You have to introduce the alias for the table ("as t"). Also, if the data from the tables is disjoint, you might want to consider switching to UNION ALL - UNION by itself works to eliminate duplicates in the result set. This is frequently not necessary.
A simple to read solution is to use a CTE (common table expression). This takes the form:
WITH foobar AS (
SELECT foo, bar FROM table_1
UNION
SELECT foo, bar FROM table_2
)
Then you can refer to the CTE in subsequent queries by name, as if it were a normal table:
SELECT foo,bar FROM foobar WHERE foo = 'value'
CTEs are quite powerful, I recommend further reading here
One tip that you will not find in that MS article is; if you require more than one CTE put a comma between the expression statements. eg:
WITH foo AS (
SELECT thing FROM place WHERE field = 'Value'
),
bar AS (
SELECT otherthing FROM otherplace WHERE otherfield = 'Other Value'
)
If you want to filter the query based on some criteria then you could do this -
Select * from table_1 where table_1.col1 = <some value>
UNION
Select * from table_2 where table_2.col1 = <some value>
But, I would say if you want to filter result to find the common values then you can use joins instead
Select * from table_1 inner join table_2 on table_1.col1 = table_2.col1

Having "___ in (select distinct ___ from #temp)" in Case statement

I'm trying to achieve this
select
case
when Org_CD = '1111' or Org_CD in (select distinct New_Org_CD from #temp) then 'International'
end as 'Organisation',
count(*)
from #AnotherTempTable
group by
case
when Org_CD = '1111' or Org_CD in (select distinct New_Org_CD from #temp) then 'International'
end
I received this error:
Column '#AnotherTempTable.Org_Cd' is
invalid in the select list because it
is not contained in either an
aggregate function or the GROUP BY
clause.
Is it because I cannot use "in" keyword inside the case statements? If yes, any known workarounds would be more than helpful!
I'd try this...
select
Org_CD, count(*)
from
#AnotherTempTable A
JOIN
(select distinct New_Org_CD from #temp UNION SELECT '1111') T ON A.Org_CD = T.New_Org_CD
group by
Org_CD
You can't have an inline IN like this (CASE + aggregate)
If this is not OK, please give sample data and output
I solved it with a variation of gbn's solution using 'Union'. Thanks all.