sql: where subquery not null - sql

I have the following sql query and I want to filter the results where the alias imagefile is null, but I can't get it to work. it's kinda basic sql... sorry for that!
SELECT Categorie.CategorieID, Categorie.Highlight, CategorieTaal.CategorieNaam,
(SELECT TOP (1) ImageFile
FROM Artikel WHERE (CategorieID = Categorie.CategorieID)
AND (Onzichtbaar = 0)
AND (NietBestelbaar = 0)
AND (Voorraad = - 1000 OR Voorraad > LevertijdDrempel)
ORDER BY Volgnummer, ArtikelID DESC) AS 'imagefile'
FROM Categorie INNER JOIN
CategorieTaal ON
Categorie.CategorieID = CategorieTaal.CategorieID
WHERE (Categorie.CategorieGroepID = #catgroepid)
AND (Categorie.Onzichtbaar = 0)
AND (CategorieTaal.TaalCode = #tc)
ORDER BY Categorie.Volgnummer, CategorieTaal.CategorieNaam

You might want to try this:
SELECT Categorie.CategorieID, Categorie.Highlight, CategorieTaal.CategorieNaam,
FROM Categorie
INNER JOIN
CategorieTaal ON
Categorie.CategorieID = CategorieTaal.CategorieID
WHERE (Categorie.CategorieGroepID = #catgroepid)
AND (Categorie.Onzichtbaar = 0)
AND (CategorieTaal.TaalCode = #tc)
AND NOT EXISTS (SELECT 1 ImageFile
FROM Artikel WHERE (CategorieID = Categorie.CategorieID)
AND (Onzichtbaar = 0)
AND (NietBestelbaar = 0)
AND (Voorraad = - 1000 OR Voorraad > LevertijdDrempel))
ORDER BY Categorie.Volgnummer, CategorieTaal.CategorieNaam

You can optimize this by using an inner join again, in lieu of trying to use a subquery twice:
SELECT
c.CategorieID,
c.Highlight,
ct.CategorieNaam,
a.ImageFile
FROM
Categorie c
INNER JOIN CategorieTaal ct ON
c.CategorieID = ct.CategorieID
INNER JOIN
(select
CategorieID,
ImageFile,
row_number() over (partition by CategorieID) as rownum
from
Artikel
where
Onzichtbaar = 0
and NietBestelbaar = 0
and (Voorraad = -1000 OR Voorraad > LevertijdDrempel)) a ON
c.CategorieID = a.CategorieID
and a.rownum = 1
WHERE
c.CategorieGroepID = #catgroepid
AND c.Onzichtbaar = 0
AND ct.TaalCode = #tc
ORDER BY c.Volgnummer, ct.CategorieNaam
Since you're using SQL Server (or at least I think you are, with your top and whatnot), you can take advantage of row_number. This will bring back just the ImageFile you need, without having to do two correlated subqueries (usually performance killers).
Also, here you only have to maintain that subquery in one place, not in two different parts of your query.

found it!!
SELECT Categorie.CategorieID, Categorie.Highlight, CategorieTaal.CategorieNaam,
(SELECT TOP (1) ImageFile
FROM Artikel
WHERE (CategorieID = Categorie.CategorieID)
AND (Onzichtbaar = 0)
AND (NietBestelbaar = 0)
AND (Voorraad = - 1000
OR Voorraad > LevertijdDrempel)
ORDER BY Volgnummer, ArtikelID DESC) AS 'imagefile'
FROM Categorie
INNER JOIN CategorieTaal ON Categorie.CategorieID = CategorieTaal.CategorieID
WHERE (Categorie.CategorieGroepID = #catgroepid)
AND (Categorie.Onzichtbaar = 0)
AND (CategorieTaal.TaalCode = #tc)
AND ((
SELECT TOP (1) ImageFile
FROM Artikel AS Artikel_1
WHERE (CategorieID = Categorie.CategorieID)
AND (Onzichtbaar = 0)
AND (NietBestelbaar = 0)
AND (Voorraad = - 1000
OR Voorraad > LevertijdDrempel)
) IS NOT NULL)
ORDER BY Categorie.Volgnummer, CategorieTaal.CategorieNaam

Related

How resolve a error that a subquery is not introduced with EXISTS?

I am trying to run my query but I get an error.
This is my query:
SELECT DISTINCT
F.FORN_ID,
F.FORN_COD,
F.FORN_DESC,
FORN_CEP,
FORN_CNPJ,
F.PAIS_COD,
F.REGI_COD,
(SELECT TOP 1 CONT_NOME FROM CONT_CONTATOS WHERE CONT_PRINCIPAL = 1 AND SEGM_COD = #SEGM_COD AND CONT_INATIVO = 0 AND FORN_ID IN(SELECT FORN_ID FROM FORN_FORNECEDORES WHERE MSTR_ID = F.FORN_ID)) AS CONT_NOME,
(SELECT TOP 1 CONT_EMAIL FROM CONT_CONTATOS WHERE CONT_PRINCIPAL = 1 AND SEGM_COD = #SEGM_COD AND CONT_INATIVO = 0 AND FORN_ID IN(SELECT FORN_ID FROM FORN_FORNECEDORES WHERE MSTR_ID = F.FORN_ID)) AS CONT_EMAIL,
(SELECT TOP 1 SEGM_COD FROM CONT_CONTATOS WHERE CONT_PRINCIPAL = 1 AND SEGM_COD = #SEGM_COD AND CONT_INATIVO = 0 AND FORN_ID IN(SELECT FORN_ID FROM FORN_FORNECEDORES WHERE MSTR_ID = F.FORN_ID)) AS SEGM_COD,
(SELECT FORN.* FROM FORNECEDORES_PERFIL as FORN
LEFT JOIN PERF_PERFIL as PERFIL
ON FORN.PERF_COD = PERFIL.PERF_COD
LEFT JOIN FAB_FABRICA as FAB ON FORN.FAB_COD = FAB.FAB_COD
LEFT JOIN TIPO_FABRICAS as TIPO_FAB ON FORN.TP_FAB_COD = TIPO_FAB.TP_FAB_COD
WHERE FORN_ID = F.FORN_ID
) AS PROFILE,
--C.CONT_NOME,
--C.CONT_TEL,
--C.CONT_TEL2,
--C.CONT_CEL,
--C.CONT_EMAIL,
--C.SEGM_COD,
F.FEIR_COD,
FE.FEIR_DESC,
F.CREATE_DATE,
F.FORN_STATUS,
F.USU_COD,
(SELECT COUNT(CONT_ID) FROM CONT_CONTATOS WHERE CONT_PRINCIPAL = 1 AND SEGM_COD = #SEGM_COD AND CONT_INATIVO = 0 AND FORN_ID IN(SELECT FORN_ID FROM FORN_FORNECEDORES WHERE MSTR_ID = FORN_ID)) AS COUNT_CONT_PRINCIPAL,
F.PLAT_ID,
F.MSTR_ID,
F.CODE,
(SELECT SEGM_COD FROM FORNECEDORES_FAVORITOS WHERE SEGM_COD = #SEGM_COD AND FORN_ID = F.FORN_ID) AS FAVORITES,
(SELECT COUNT(NOTA_ID) FROM NOTA_NOTAS WHERE SEGM_COD = #SEGM_COD AND TP_NOTA_ID = 2 AND NOTA_INATIVA = 0 AND OBJ_ID = F.FORN_ID) AS NOTA_COUNT,
ROW_NUMBER() OVER(ORDER BY F.FORN_ID) AS LINHA,
F.UPDATE_DATE
FROM FORN_FORNECEDORES F
LEFT OUTER JOIN FEIR_FEIRAS FE (nolock) ON FE.FEIR_COD = F.FEIR_COD
--LEFT OUTER JOIN END_ENDERECOS E ON E.FORN_ID = F.FORN_ID
--LEFT OUTER JOIN CONT_CONTATOS C ON C.FORN_ID = F.FORN_ID AND C.CONT_PRINCIPAL = 1 AND C.CONT_INATIVO = 0
WHERE (F.FORN_DESC like '%'+#FORN_DESC+'%' or #FORN_DESC IS NULL)
AND (F.FEIR_COD = #FEIR_COD or #FEIR_COD IS NULL)
AND (F.FORN_ID = #FORN_ID or #FORN_ID IS NULL)
AND (F.FORN_STATUS = #FORN_STATUS or #FORN_STATUS IS NULL)
AND (F.USU_COD = #USUARIO_ID OR #USUARIO_ID IS NULL)
AND (CONVERT(VARCHAR(10),F.CREATE_DATE,102) >= CONVERT(VARCHAR(10),#CREATE_DATE_I,102)or #CREATE_DATE_I IS NULL)
AND (CONVERT(VARCHAR(10),F.CREATE_DATE,102) <= CONVERT(VARCHAR(10),#CREATE_DATE_F,102) or #CREATE_DATE_F IS NULL)
AND (CONVERT(VARCHAR(10),F.UPDATE_DATE,102) >= CONVERT(VARCHAR(10),#UPDATE_DATE,102)or #UPDATE_DATE IS NULL)
AND FORN_INATIVO = 0
AND F.FORN_ID = F.MSTR_ID
`
the error is exactly when I added this sub query
(SELECT FORN.* FROM FORNECEDORES_PERFIL as FORN
LEFT JOIN PERF_PERFIL as PERFIL
ON FORN.PERF_COD = PERFIL.PERF_COD
LEFT JOIN FAB_FABRICA as FAB ON FORN.FAB_COD = FAB.FAB_COD
LEFT JOIN TIPO_FABRICAS as TIPO_FAB ON FORN.TP_FAB_COD = TIPO_FAB.TP_FAB_COD
WHERE FORN_ID = F.FORN_ID
) AS PROFILE,
I observed some random questions but none of them worked, I even tried to add FORN.* but without success
This error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
It's this subquery in the SELECT clause:
(SELECT FORN.* FROM FORNECEDORES_PERFIL as FORN
LEFT JOIN PERF_PERFIL as PERFIL
ON FORN.PERF_COD = PERFIL.PERF_COD
LEFT JOIN FAB_FABRICA as FAB ON FORN.FAB_COD = FAB.FAB_COD
LEFT JOIN TIPO_FABRICAS as TIPO_FAB ON FORN.TP_FAB_COD = TIPO_FAB.TP_FAB_COD
WHERE FORN_ID = F.FORN_ID
) AS PROFILE,
Each item in the SELECT clause is only allowed to have ONE value. However, the subquery returns FORN.*, which is many values. If you really want to include every column from the subquery in the results, you may try using an APPLY lateral join instead.

How to avoid union all

Any possibility methods to avoiding "Union all" when different joining > conditions varies on each section
SELECT RS1.*, EXL.*
FROM "EXL" "EXL"
INNER JOIN "RS1" "RS1"
ON "RS1"."HEADER_KEY" = "EXL"."HEADER_KEY"
WHERE "RS1"."PIPE_KEY" = '1109' AND
"RS1"."COLK" IS NULL AND
"RS1".CT1 = 0 AND "RS1".CT2 > 0
UNION ALL
SELECT RS1.*, EXL.*
FROM "EXL" "EXL"
INNER JOIN "RS1" "RS1"
ON "RS1"."HEADER_KEY" = "EXL"."HEADER_KEY"
INNER JOIN "YFS"."STATUS_MAP" "SOS"
ON "SOS"."STATUS" = "RS1"."STATUS"
INNER JOIN "RS1" "RS2"
ON "RS2"."LINE_KEY" = "RS1"."CHAINLINE_KEY" AND
"RS2"."PIPEKEY" = "SOS"."TYPE_KEY" AND
"RS2"."STATUS" = "SOS"."EXTN_STATUS" AND
"RS2"."PIPE_KEY" = '4093'
WHERE "RS1"."PIPE_KEY" = '1109' AND
"RS1"."COLK" IS NULL AND
"RS1".CT1 = 0 AND "RS1".CT2 > 0
Since the two SELECTs have exactly the same WHERE-condition, I assume that you want to return rows from EXL, even when rows from YFS.STATUS_MAP are missing (otherwise please explain what your intention is). You can do this with LEFT JOIN
SELECT RS1.*, EXL.*
FROM
"EXL"
INNER JOIN "RS1"
ON "RS1"."HEADER_KEY" = "EXL"."HEADER_KEY"
LEFT JOIN "YFS"."STATUS_MAP" "SOS"
ON "SOS"."STATUS" = "RS1"."STATUS"
LEFT JOIN "RS1" "RS2"
ON "RS2"."LINE_KEY" = "RS1"."CHAIN_LINE_KEY" AND
"RS2"."PIPEKEY" = "SOS"."TYPE_KEY" AND
"RS2"."STATUS" = "SOS"."EXTN_STATUS" AND
"RS2"."PIPELINE_KEY" = '4093'
WHERE "RS1"."PIPELINE_KEY" = '1109' AND
"RS1"."COLK" IS NULL AND
"RS1".CT1 = 0 AND "RS1".CT2 > 0

Sql Multi Levels Aggregation

I have this DB diagram:
Considering the relations in the diagram I want to calculate the sum of LikesCount for each RoomType the sum of likes count is to be calculated like that:
RoomTypeLikesCount = Sum(Replays.LikesCount) +
Sum(Comments.LikesCount) +
Sum(Posts.LikesCount)
According to the relation in the diagram as distinct count.
I wonder if there is any simple high performing way.
[Update]
Note: I want to exclude archived or blocked records and just consider rooms with isVisible = true.
My attempt is:
--get comment replays likes, dislikes counts [SUM]
SELECT
C.PostID, C.CommentID,
ISNULL(COUNT(RP.ReplayID), 0) ReplayCount,
ISNULL(C.LikesCount, 0) + ISNULL(SUM(RP.LikesCount), 0) LikesCount,
ISNULL(C.DislikesCount, 0) + ISNULL(SUM(RP.DislikesCount), 0) DislikesCount
INTO
#CommentStats
FROM
CollaborationDB.DiscussionRooms.Comments C
LEFT JOIN
DiscussionRooms.Replays RP ON RP.CommentID = C.CommentID
AND RP.IsBlocked = 0
AND RP.IsArchived = 0
WHERE
c.IsBlocked = 0
AND C.IsArchived = 0
GROUP BY
C.PostID, C.CommentID, C.LikesCount, C.DislikesCount
--get posts views, likes, dislikes counts
SELECT
P.RoomID, P.PostID, P.ViewsCount,
ISNULL(COUNT(CS.CommentID), 0) + ISNULL(SUM(ReplayCount), 0) CommentCount,
ISNULL(P.LikesCount, 0) + ISNULL(SUM(CS.LikesCount), 0) LikesCount,
ISNULL(P.DislikesCount, 0) + ISNULL(SUM(CS.DislikesCount), 0) DislikesCount
INTO
#PostStats
FROM
CollaborationDB.DiscussionRooms.Posts P
LEFT JOIN
#CommentStats CS ON CS.PostID = P.PostID
AND P.IsBlocked = 0
AND P.IsArchived = 0
GROUP BY
P.RoomID, P.PostID, P.ViewsCount, P.LikesCount, P.DislikesCount
--get Room Types Rooms, Posts, views, likes, dislikes counts
SELECT
RT.TypeName,
ISNULL(COUNT(DISTINCT R.RoomID), 0) [RoomsCount],
ISNULL(COUNT(DISTINCT PS.PostID), 0) [PostsCount],
ISNULL(SUM(PS.LikesCount), 0) LikesCount,
ISNULL(SUM(PS.DislikesCount), 0) DislikesCount,
ISNULL(SUM(PS.ViewsCount), 0) ViewsCount
FROM
CollaborationDB.DiscussionRooms.RoomTypes RT
LEFT JOIN
CollaborationDB.DiscussionRooms.Rooms R ON R.RoomTypeID = RT.RoomTypeID
AND R.IsVisible = 1
AND R.IsArchived = 0
LEFT JOIN
#PostStats PS ON PS.RoomID = R.RoomID
WHERE
rt.IsArchived = 0
AND R.IsVisible = 1
AND R.IsArchived = 0
GROUP BY
RT.RoomTypeID, RT.TypeName

Convert to linq sql query error

I have a query according to the :
SELECT
tblDefinition.TopsisType, tblTemplate.tType, tblEvaluationFormCategory.Title AS EvaluationCategory,
CASE tType WHEN 1 THEN N'2'
ELSE N'1' END ProcessType,
tblDefinition.Description, tblDefinition.TemplateID, 1 Destinition
FROM tblTemplate INNER JOIN
tblEvaluationFormCategory ON tblTemplate.CategoryID = tblEvaluationFormCategory.ID INNER JOIN
tblEFQMAlternative INNER JOIN
tblDefinition ON ([tblEFQMAlternative].[TopsisID] = [tblDefinition].[TopsisID] AND [tblEFQMAlternative].[CustomerID] = [tblDefinition].[CustomerID]) INNER JOIN
tblGroupMembers ON ([tblDefinition].[TopsisID] = [tblGroupMembers].[TopsisID]
AND tblDefinition.CustomerID =
tblGroupMembers.CustomerID) ON tblTemplate.TemplateID = tblDefinition.TemplateID
INNER JOIN
tblTerm ON tblDefinition.TermGrant = tblTerm.Title
WHERE (tblTerm.ID = 20) AND (tblGroupMembers.UserID = 558)
GROUP BY tblDefinition.TopsisType, tblTemplate.tType, tblEvaluationFormCategory.Title,
tblDefinition.Description, tblDefinition.TemplateID
when i convert to linq, then error to :
Field [([tblDefinition].[TopsisID] = [tblGroupMembers]].[[TopsisID] AND tblDefinition.CustomerID = tblGroupMembers.CustomerID) ON tblTemplate.TemplateID] not found in the current Data Context.
What should I do?

SQL UPDATE using two joined subqueries

I wrote a query that does an inner join of two subqueries. The first subquery has an alias of "SRC" and the other has an alias of "DEST". What I want to do is update some fields in the table NomineeActionLegislatorVoteDetail (part of DEST subquery) with values from the table Nominee_Committee_Vote (part of SRC subquery). It souds easy but I just cannot figure out how to do it. Does anyone have any suggestions? Any help would be appreciated.
Here is the query I wrote:
select *
from (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC
inner join (
select votedetail.*
from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
Can you insert the update in front of the sub queries
UPDATE NomineeActionLegislatorVoteDetail
SET NomineeActionLegislatorVoteDetail.COLUMNNAME = src.VALUE
--SubQueriesBelow
from
(select ncv.*, na.NomineeActionId, l.LegislatorId from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId) SRC
inner join
(select votedetail.* from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
It looks like the update is on a table in the sub query so it could be re factored to have one subquery
I've adjusted the lay-out of your query a bit to disclose better where subqueries start and end. In your DEST subquery, you join NomineeAction but you don't select any columns from it, so it only filters rows from NomineeActionLegislatorVoteDetail for which no NomineeAction exists. So really you wanna be updating and joining on columns from NomineeActionLegislatorVoteDetail exclusively. Based on that, I would write the update query like so:
update votedetail set
votedetail.SomeColumn = SomeValue,
votedetail.SomeOtherColumn = SomeOtherValue
from azleg..NomineeActionLegislatorVoteDetail votedetail
join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
join (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC on
SRC.agency_id = votedetail.x_agency_id and
SRC.position_id = votedetail.x_position_id and
SRC.nominee_id = votedetail.x_nominee_id and
SRC.received_date = votedetail.x_received_date and
SRC.session_id = votedetail.x_session_id and
SRC.committee_id = votedetail.x_committee_id and
SRC.member_id = votedetail.x_member_id
where SRC.NomineeActionId <> votedetail.NomineeActionId
OR SRC.LegislatorId <> votedetail.LegislatorId
OR SRC.Vote <> votedetail.Vote