Subquery and NOT NULL - sql-server

I need some help with a subquery. My test column sometimes comes back NULL and if so I want to filter those out of my results set.
My stored procedure looks like this
SELECT
pl.Id AS Id,
pl.Name AS Name,
f.[Url] AS PrimaryImageUrl,
up.Id AS MemberId,
up.ProfessionalName,up.
AvatarUrl,
test = (SELECT
c.Id AS Id,
c.Name AS Name,
c.ContentImageUrl AS ImageUrl,
c.Price AS Price,
c.BPM AS BPM,
f.Id AS 'File.Id',
f.Url AS 'File.Name',
TotalCount = COUNT (c.Id) OVER()
FROM
dbo.Content c
INNER JOIN
dbo.PlayListContents pm ON c.Id = pm.ContentId
AND pm.PlaylistId = pl.Id
INNER JOIN
dbo.Files f ON c.ContentFileId = f.Id
FOR JSON PATH),
TotalCount = COUNT(1) OVER()
FROM
dbo.Playlist pl
INNER JOIN
dbo.UserProfiles up ON pl.UserId = up.UserId
INNER JOIN
[dbo].[Files] AS f ON pl.[PrimaryImageId] = f.[Id]
WHERE
(pl.Name LIKE '%' + #searchInput + '%')
AND test IS NOT NULL
Why is this last line, AND test IS NOT NULL invalid? I need my result set to have all results with test being NOT NULL

Try this
SELECT * FROM
(Select pl.Id as Id
,pl.Name as Name
,f.[Url] as PrimaryImageUrl
,up.Id as MemberId
,up.ProfessionalName
,up.AvatarUrl
,test = ( select c.Id as Id
,c.Name as Name
,c.ContentImageUrl as ImageUrl
,c.Price as Price
,c.BPM as BPM
,f.Id as 'File.Id'
,f.Url as 'File.Name'
,TotalCount = count(c.Id)Over()
from dbo.Content c
inner join dbo.PlayListContents pm on c.Id = pm.ContentId and pm.PlaylistId = pl.Id
inner join dbo.Files f on c.ContentFileId = f.Id
for json path)
--,TotalCount = COUNT(1) OVER()
from dbo.Playlist pl
inner join dbo.UserProfiles up on pl.UserId = up.UserId
inner join [dbo].[Files] as f ON pl.[PrimaryImageId] = f.[Id]
where ( pl.Name LIKE '%' + #searchInput + '%')) a
WHERE a.test IS NOT NULL

Columns in the SELECT are not available in the WHERE, due to SQL's logical order of operations.
Instead, place the value in CROSS APPLY, then filter after that:
SELECT
pl.Id AS Id,
pl.Name AS Name,
f.[Url] AS PrimaryImageUrl,
up.Id AS MemberId,
up.ProfessionalName,up.
AvatarUrl,
v.test,
TotalCount = COUNT(1) OVER()
FROM
dbo.Playlist pl
INNER JOIN
dbo.UserProfiles up ON pl.UserId = up.UserId
INNER JOIN
[dbo].[Files] AS f ON pl.[PrimaryImageId] = f.[Id]
CROSS APPLY (
SELECT test =
(SELECT
c.Id AS Id,
c.Name AS Name,
c.ContentImageUrl AS ImageUrl,
c.Price AS Price,
c.BPM AS BPM,
f.Id AS 'File.Id',
f.Url AS 'File.Name',
TotalCount = COUNT (c.Id) OVER()
FROM
dbo.Content c
INNER JOIN
dbo.PlayListContents pm ON c.Id = pm.ContentId
AND pm.PlaylistId = pl.Id
INNER JOIN
dbo.Files f ON c.ContentFileId = f.Id
FOR JSON PATH
)
) v
WHERE
(pl.Name LIKE '%' + #searchInput + '%')
AND v.test IS NOT NULL;

Related

WHERE is not null for correlated subquery

My proc looks like this :
Select pl.Id as Id,
pl.Name as Name,
f.[Url] as PrimaryImageUrl,
up.Id as MemberId,
up.ProfessionalName,
up.AvatarUrl,
(
select c.Id as Id,
c.Name as Name,
c.ContentImageUrl as ImageUrl,
c.Price as Price,
c.BPM as BPM,
f.Id as 'File.Id',
f.Url as 'File.Name',
g.Id as 'Genre.Id',
g.Name as 'Genre.Name',
kt.Id as 'KeyType.Id',
kt.Name as 'KeyType.Name',
tt.Id as 'TrackType.Id',
tt.Name as 'TrackType.Name',
TotalCount = count(c.Id) Over ()
from dbo.Content c
inner join dbo.PlayListContents pm
on c.Id = pm.ContentId
and pm.PlaylistId = pl.Id
inner join dbo.Files f
on c.ContentFileId = f.Id
inner join dbo.Genres g
on c.GenreTypeId = g.Id
inner join dbo.KeyType kt
on c.KeyTypeId = kt.Id
inner join dbo.TrackType tt
on tt.Id = c.TrackTypeId
Where (NOT EXISTS (
SELECT b.Bpm
FROM #Bpm AS b
WHERE b.Bpm IS NOT NULL)
OR c.Bpm IN (SELECT * FROM #Bpm)
)
for json path
) AS Content,
TotalCount = COUNT(1) OVER ()
from dbo.Playlist pl
inner join dbo.UserProfiles up
on pl.UserId = up.UserId
inner join [dbo].[Files] as f
ON pl.[PrimaryImageId] = f.[Id]
where (pl.Name LIKE '%' + #searchInput + '%')
Using this proc I sometimes get results with Content column at NULL.
why can't I add WHERE Content IS NOT NULL and have my results come back with no rows with NULL at Content column?

Column name doesn't exist in CTE statement

I'm trying to create a CTE statement:
WITH StartCash (StartCash) AS
(
SELECT StartCash
FROM CashierInfo
WHERE CashierID = (SELECT MAX( CashierID)
FROM CashierInfo
WHERE UserID = 1 AND EndDate IS NULL)
)
SELECT
StartCash, a.username AS Username, b.Adress AS Adress,
(SUM(c.quantity * c.discountprice)) AS SumPrice,
c.Printed AS Printed, c.CashierUserID AS CashierUserID,
c.RetailDelivery AS RetailDelivery, c.TrnDocumentID
FROM
Users a
JOIN
InventoryTransTemp c ON c.CashierUserID = a.UserID
JOIN
DeliveryAdress b ON b.DeliveryAdressID = c.DeliveryAdressID
WHERE
c.cashieruserid = 1
GROUP BY
a.Username, b.Adress, c.Printed,
c.CashierUserID, c.RetailDelivery, c.TrnDocumentID
But I am getting an error
Invalid column name 'StartCash'
StartCash does not exist because your CTE is not included in your FROM clause.
Based solely on what I can see in your question, I assume it would be safe to JOIN CashierInfo.UserID to Users.UserID.
So try something like this:
WITH StartCash
AS (
SELECT StartCash
,UserID
FROM CashierInfo
WHERE CashierID = (
SELECT MAX(CashierID)
FROM CashierInfo
WHERE UserID = 1
AND EndDate IS NULL
)
)
SELECT sc.StartCash
,a.username AS Username
,b.Adress AS Adress
,(SUM(c.quantity * c.discountprice)) AS SumPrice
,c.Printed AS Printed
,c.CashierUserID AS CashierUserID
,c.RetailDelivery AS RetailDelivery
,c.TrnDocumentID
FROM StartCash sc
INNER JOIN Users a ON sc.UserID = a.UserID
INNER JOIN InventoryTransTemp c ON c.CashierUserID = a.UserID
INNER JOIN DeliveryAdress b ON b.DeliveryAdressID = c.DeliveryAdressID
WHERE c.cashieruserid = 1
GROUP BY sc.StartCash
,a.Username
,b.Adress
,c.Printed
,c.CashierUserID
,c.RetailDelivery
,c.TrnDocumentID
You do not have the CTE in the from clause. You need to join to the CTE but your CTE has only a summary value. https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-2017

SQL query to fetch repeat column values within time frame

I have an eCommerce website where I am getting lot of fraud orders.. I'd like to pull out those Order_No.
Here is my query
SELECT
O.Order_No, O.Customer_ID, O.DateOrdered, O.IPAddress,
C.FirstName, C.LastName, CD.nameoncard
FROM
Order_No O
INNER JOIN
CardData CD ON O.card_id = CD.id
INNER JOIN
Customers C ON O.customer_id = C.customer_id
ORDER BY
O.order_no desc
Here's the criteria I want to follow:
If the customer_id repeats more than once in 6hrs
If the IPAddress repeats more than once in 6hrs
If the Lastname is NOT found in Nameoncard
Can someone help please?
can you try this
WITH Tmp (Order_No, Customer_id, DateOrdered, IPAddress, FirstName, LastName, NameOnCard)
AS
(
SELECT Ord.Order_No, Ord.Customer_Id, Ord.DateOrdered, Ord.IPAddress,
Cust.FirstName, Cust.LastName, CustData.NameOnCard
FROM Order_No Ord
INNER JOIN Customers Cust
ON
Cust.Customer_Id = Ord.Customer_Id
INNER JOIN
CardData CustData
ON CustData.Id = Ord.Card_Id
)
SELECT DISTINCT a.*
FROM Tmp a
INNER JOIN Tmp b
ON a.Order_No <> b.Order_No
AND a.Customer_Id = b.Customer_Id
WHERE DATEDIFF(hour, a.DateOrdered, b.DateOrdered) >= 6
UNION
SELECT DISTINCT c.*
FROM Tmp c
INNER JOIN Tmp d
ON c.Order_No <> d.Order_No
AND c.IPAddress = d.IPAddress
WHERE DATEDIFF(hour, c.DateOrdered, d.DateOrdered) >= 6
UNION
SELECT DISTINCT e.*
FROM Tmp e
WHERE ISNULL(e.NameOnCard,'') = ''
here is the query:
select * from
(
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.customer_id=b.customer_id
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.IPAddress=b.IPAddress
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select a.order_no,a.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
inner join carddata as cd on a.customer_id=cd.customer_id
INNER JOIN Customers C ON a.customer_id = C.customer_id
where charindex(C.LastName,cd.nameoncard) = 0
) as abc

sql server 2008, how to get rid of duplications when inner join 3 tables

here's my query. when I inner join 2 tables, there's no problem.
SELECT S.* ,
U.Avatar ,
U.Displayname ,
ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
WHERE S.IsPublic = 1
AND S.Status = 3
AND S.UserId = 2
then, I added another inner join. now, I got alot duplications.
SELECT S.* ,
U.Avatar ,
U.Displayname,
ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
one solutions is to use distinct. however, I have to comment out row_number, i need that row_number to do paging. is there another way to get rid of duplication?
SELECT DISTINCT S.* ,
U.Avatar ,
U.Displayname
-- ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
Why not use the query you have, without the row_number as a subquery, then add the row number back later:
SELECT *,
ROW_NUMBER() OVER ( ORDER BY subQuery.Id DESC ) rownum
FROM (
SELECT DISTINCT S.* ,
U.Avatar ,
U.Displayname
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
) AS subQuery
Dense_Rank would also do the job with the your otherwise unmodified query.

Get the most value from another column

I want to get data historical and the production. My stored procedure is as follows:
ALTER PROCEDURE [dbo].[pCaRptACInactivas](
#CodAsesor VARCHAR(15),
#CodOficina VARCHAR(4))
AS
SET NOCOUNT ON
DECLARE #CodArbolConta VARCHAR(25)
IF #CodOficina = '%'
SET #CodArbolConta = '%'
ELSE
SELECT #CodArbolConta = CodArbolConta + '%' FROM tClOficinas WHERE CodOficina LIKE #CodOficina
SELECT
tabACInactivas.CodOficina,
tabACInactivas.NomOficina,
tabACInactivas.NomAsesor,
MAX(tabACInactivas.CodPrestamo) CodPrestamo,
tabACInactivas.CodAsociacion,
tabACInactivas.NombreAsociacion,
MAX(tabACInactivas.Ciclo) AS Ciclo,
COUNT(DISTINCT tabACInactivas.CodUsuario) AS CantSocias,
MAX(tabACInactivas.FechaEstado) AS FechaCancelacion--,
FROM ( SELECT tClOficinas.CodOficina, tClOficinas.NomOficina, tCaClAsesores.CodAsesor, tCaClAsesores.NomAsesor, tCaPrestamos.CodPrestamo, tCaAsociacion.CodAsociacion, tCaAsociacion.NombreAsociacion, tCaPrestamos.Ciclo, tCaPrCliente.CodUsuario, tCaPrestamos.FechaEstado, tClParametros.FechaProceso FROM tCaPrestamos WITH(NOLOCK) INNER JOIN tCaProducto WITH(NOLOCK) ON tCaProducto.CodProducto = tCaPrestamos.CodProducto INNER JOIN tClOficinas WITH(NOLOCK) ON tClOficinas.CodOficina = tCaPrestamos.CodOficina INNER JOIN tCaAsociacion WITH(NOLOCK) ON tCaAsociacion.CodAsociacion = tCaPrestamos.CodAsociacion INNER JOIN tCaPrCliente WITH(NOLOCK) ON tCaPrCliente.CodPrestamo = tCaPrestamos.CodPrestamo INNER JOIN tClParametros WITH(NOLOCK) ON tClParametros.CodOficina = tClOficinas.CodOficina INNER JOIN tCaClAsesores ON tCaClAsesores.CodAsesor = tCaAsociacion.CodAsesor WHERE tCaPrestamos.Estado = 'CANCELADO' AND DATEDIFF(DAY, tCaPrestamos.FechaEstado, tClParametros.FechaProceso) > 30 AND NOT EXISTS(SELECT 1
FROM tCaPrestamos Pr
INNER JOIN tCaPrCliente PrCl ON PrCl.CodPrestamo = Pr.CodPrestamo
WHERE Pr.Estado NOT IN ('TRAMITE', 'APROBADO')
AND Pr.FechaDesembolso >= tCaPrestamos.FechaEstado
AND Pr.CodAsociacion = tCaPrestamos.CodAsociacion
) AND tCaProducto.Tecnologia = 3 AND tCaPrestamos.CodAsesor LIKE #CodAsesor AND tCaPrestamos.CodOficina IN (SELECT CodOficina FROM tClOficinas WHERE CodArbolConta LIKE #CodArbolConta)
UNION ALL
SELECT tClOficinas.CodOficina, tClOficinas.NomOficina, tCaClAsesores.CodAsesor, tCaClAsesores.NomAsesor, tCaHPrestamos.CodPrestamo, tCaAsociacion.CodAsociacion, tCaAsociacion.NombreAsociacion, tCaHPrestamos.Ciclo, tCaHPrCliente.CodUsuario, tCaHPrestamos.FechaEstado, tClParametros.FechaProceso FROM tCaHPrestamos WITH(NOLOCK) INNER JOIN tCaProducto WITH(NOLOCK) ON tCaProducto.CodProducto = tCaHPrestamos.CodProducto INNER JOIN tClOficinas WITH(NOLOCK) ON tClOficinas.CodOficina = tCaHPrestamos.CodOficina INNER JOIN tCaAsociacion WITH(NOLOCK) ON tCaAsociacion.CodAsociacion = tCaHPrestamos.CodAsociacion INNER JOIN tCaHPrCliente WITH(NOLOCK) ON tCaHPrCliente.CodPrestamo = tCaHPrestamos.CodPrestamo INNER JOIN tClParametros WITH(NOLOCK) ON tClParametros.CodOficina = tClOficinas.CodOficina INNER JOIN tCaClAsesores ON tCaClAsesores.CodAsesor = tCaAsociacion.CodAsesor WHERE tCaHPrestamos.Estado = 'CANCELADO' AND DATEDIFF(DAY, tCaHPrestamos.FechaEstado, tClParametros.FechaProceso) > 30 AND NOT EXISTS(SELECT 1
FROM tCaHPrestamos Pr
INNER JOIN tCaHPrCliente PrCl ON PrCl.CodPrestamo = Pr.CodPrestamo
WHERE Pr.Estado NOT IN ('TRAMITE', 'APROBADO')
AND Pr.FechaDesembolso >= tCaHPrestamos.FechaEstado
AND Pr.CodAsociacion = tCaHPrestamos.CodAsociacion
) AND tCaProducto.Tecnologia = 3 AND tCaHPrestamos.CodAsesor LIKE #CodAsesor AND tCaHPrestamos.CodOficina IN (SELECT CodOficina FROM tClOficinas WHERE CodArbolConta LIKE #CodArbolConta)
)tabACInactivas
GROUP BY tabACInactivas.CodAsociacion, tabACInactivas.NombreAsociacion, tabACInactivas.NomOficina, tabACInactivas.CodOficina, tabACInactivas.NomAsesor
I want the CantSocias column takes the most value of the Ciclo column, but not working
That stored procedure that you have posted up is way too large and blocky to even try to interpret and understand. So I will go off of your last sentence:
I want the CantSocias column takes the most value of the Ciclo column,
but not working
Basically if you want to set a specific column to that, you can do something like this:
update YourTable
set CantSocias =
(
select max(Ciclo)
from YourOtherTable
)
-- here is where you can put a conditional WHERE clause
You may need to create a sub query to get the most value of Ciclo and join back to your query.
An example of what I mean is here:
create table #Product
(
ID int,
ProductName varchar(20)
)
insert into #Product(ID, ProductName)
select 1,'ProductOne'
union
select 2,'ProductTwo'
create table #ProductSale
(
ProductID int,
Number int,
SalesRegion varchar(20)
)
insert into #ProductSale(ProductID,Number,SalesRegion)
select 1,1500,'North'
union
select 1, 1200, 'South'
union
select 2,2500,'North'
union
select 2, 3200, 'South'
--select product sales region with the most sales
select * from #Product p
select ProductId, Max(Number) as Bestsale from #ProductSale ps group by ProductID
--combining
select
p.ID,
p.ProductName,
tp.Bestsale,
ps.SalesRegion
from
#Product p
inner join
(select ProductId, Max(Number) as Bestsale from #ProductSale ps group by ProductID) as tp on p.ID = tp.ProductID
inner join
#ProductSale ps on p.ID = ps.ProductID and tp.Bestsale = ps.Number

Resources