SQL Case Statement with a Subselect - sql

select case when exists(
select top 1 1
from dg_world_records wr (nolock)
where wr.gametypeid = 4
and wr.playerid = 1
)
then totaltime = (select min(totaltime) from dg_world_records (nolock) where playerid = 1 and gametypeid = 4)
else totaltime = (select max(totaltime) from dg_world_records (nolock) where gametypeid = 4)
end
My guess is that this can't be done, but I'm trying to do a subselect within a sql case statement. Is this possible?
I'm trying to do a lookup based of finding or not finding a value in a table. I can do this by breaking up the statement, but I was wondering if it's possible to do this in a single statement.
Here is the table schema:
CREATE TABLE [dbo].[DG_WORLD_RECORDS](
[WorldRecordId] [int] IDENTITY(1,1) NOT NULL,
[GameTypeId] [int] NOT NULL,
[PlayerId] [int] NOT NULL,
[NumberOfValues] [int] NOT NULL,
[TotalTime] [int] NOT NULL,
[DateOfRecord] [datetime] NOT NULL,
[GameId] [int] NULL,
[UTCInserted] [datetime] NOT NULL CONSTRAINT [DF_DG_WORLD_RECORDSII_UTCInserted] DEFAULT (getutcdate()),
[UTCUpdated] [datetime] NOT NULL CONSTRAINT [DF_DG_WORLD_RECORDSII_UTCUpdated] DEFAULT (getutcdate()),
[SrvName] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF_DG_WORLD_RECORDSII_SrvName] DEFAULT (##servername),
CONSTRAINT [PK_DG_WORLD_RECORDS] PRIMARY KEY CLUSTERED
(
[WorldRecordId] ASC
)
)

Don't know why you are writing this crazy query, but to answer your question, yes it could be done, just move your assignment out of the case statement:
select totaltime = CAST (
case when exists(
select *
from dg_world_records wr (nolock)
where wr.gametypeid = 4 and wr.playerid = 1)
then (select min(totaltime) from dg_world_records (nolock) where playerid = 1 and gametypeid = 4)
else (select max(totaltime) from dg_world_records (nolock) where gametypeid = 4)
end AS INT)

Related

insert based on condition check in similar columns between 2 tables and add NULL when missing SQL

CREATE TABLE #temppayload(
[user_id] [int] NOT NULL,
[field_id] [int] NOT NULL,
[type_id] [int] NOT NULL,
[field_value_string] [nvarchar](4000) NULL,
[field_value_numeric] [float] NULL,
[field_value_date] [date] NULL,
[field_value_bool] [bit] NULL,
[field_value_lookup] [int] NULL
)
insert into #temppayload values (1,31,1,'NEW',NULL,NULL,NULL,NULL)
insert into #temppayload values (1,11,1,'Update1',NULL,NULL,NULL,NULL)
insert into #temppayload values (1,12,2,NULL,NULL,NULL,NULL,'4')
insert into #temppayload values (4,41,4,Null,'1',NULL,NULL,NULL)
CREATE TABLE #tempdb(
[user_id] [int] NOT NULL,
[field_id] [int] NOT NULL,
[type_id] [int] NOT NULL,
[field_value_string] [nvarchar](4000) NULL,
[field_value_numeric] [float] NULL,
[field_value_date] [date] NULL,
[field_value_bool] [bit] NULL,
[field_value_lookup] [int] NULL
)
insert into #tempdb values (1,11,1,'create1',NULL,NULL,NULL,NULL)
insert into #tempdb values (1,12,2, NULL,NULL,NULL,NULL,NULL)
insert into #tempdb values (1,13,3,NULL,NULL,'2020-04-15',NULL,NULL)
insert into #tempdb values (4,41,4,NULL,'1',NULL,NULL,NULL)
user_id field_id type_id [field_value_string] [field_value_numeric] [field_value_date] [field_value_bool] [field_value_lookup]
1 31 1 NEW NULL NULL NULL NULL
1 11 1 update1 NULL NULL NULL NULL
1 12 2 NULL NULL NULL NULL 4
1 13 3 NULL NULL NULL NULL NULL
condition
new value from payload
value change compared to payload and tempdb
insert with null when #temppayload does not have it but exist in #tempdb
i was thinking of doing not exist seperately, left join seperately and union both the result.
Adding condition like below , the approach does not look efficient to me. i tried with innerjoin and leftjoin together could not figure out.
Any help is much appreciated . Thanks in advance.
select
distinct
st.user_id
,st.field_id
,st.type_id
,st.field_value_string
,st.field_value_numeric
,st.field_value_date
,st.field_value_bool
,st.field_value_lookup
from #temppayload st
where not exists (select *
from #tempdb t
where st.user_id = t.user_id
AND st.type_id = t.type_id
AND st.field_id = t.field_id
AND st.field_value_string = t.field_value_string
AND st.field_value_string IS NULL
AND t.field_value_string Is NULL
Able to figure this out by below approach . feel free to share if there is any other efficient way to do this.
select * into #modifiedpayload FROM
(select distinct st.user_id,st.field_id,st.type_id,st.field_value_string,st.field_value_numeric,st.field_value_date,st.field_value_lookup from
#temppayload st
where not exists (select user_id,st.field_id,st.type_id,st.field_value_string,field_value_numeric from #tempdb
where st.user_id = user_id
AND st.type_id = type_id
AND st.field_id = field_id
AND (st.field_value_string IS NULL AND field_value_string IS NULL OR st.field_value_string = field_value_string)
AND (st.field_value_numeric IS NULL AND field_value_numeric IS NULL OR st.field_value_numeric = field_value_numeric)
AND (st.field_value_date IS NULL AND field_value_date IS NULL OR st.field_value_date = field_value_date)
AND (st.field_value_bool IS NULL AND field_value_bool IS NULL OR st.field_value_bool = field_value_bool)
AND (st.field_value_lookup IS NULL AND field_value_lookup IS NULL OR st.field_value_lookup = field_value_lookup)
)
UNION
select t.user_id,t.field_id,t.type_id, NULL as field_value_string, NULL as field_value_numeric, NULL as field_value_date, NULL field_value_lookup from #tempdb t
LEFT JOIN #temppayload s
on t.user_id = s.user_id AND t.field_id = s.field_id
where s.field_id IS NULL ) AS X

Update Table Variable in SQL Server and getting Must declare the scalar variable

I CAN change to temp table if need be, but when I am doing an UPDATE on a table variable in sql server, why are I getting this error
and how can I fix, should I switch to temp table ?
Must declare the scalar variable "#rpmuserTableVariable".
DECLARE #rpmuserTableVariable TABLE
(
[usr_id] [varchar](8) NOT NULL,
[usr_fnm] [varchar](64) NOT NULL,
[usr_lnm] [varchar](64) NOT NULL,
[usr_pwd] [varchar](64) NOT NULL,
[email_id] [varchar](250) NULL,
[wwid] [varchar](8) NULL,
[tel] [char](20) NULL,
[dflt_ste_id] [int] NOT NULL,
[lst_pwd_chg_dtm] [datetime] NULL,
[lst_accs_dtm] [datetime] NULL,
[apprvr_wwid] [varchar](8) NULL,
[inact_ind] [varchar](1) NOT NULL,
[cre_usr_id] [varchar](8) NOT NULL,
[cre_dtm] [datetime] NOT NULL,
[chg_usr_id] [varchar](8) NULL,
[chg_dtm] [datetime] NULL,
[salt] [varchar](20) NULL,
STATUS [char] (1) NULL
);
-- All Active Users
INSERT INTO #rpmuserTableVariable
SELECT * ,'0'
FROM rpm_scrty_rpm_usr WITH(NOLOCK)
WHERE inact_ind = 'N'
-- Internal Users
UPDATE #rpmuserTableVariable
SET STATUS = 1
FROM rpm_scrty_rpm_usr ru WITH(NOLOCK)
INNER JOIN rpm_scrty_emp_info ei WITH(NOLOCK)
ON ru.wwid = ei.wwid
WHERE ru.inact_ind = 'N'
AND ei.inact_ind = 'N'
AND ei.dmn_addr IS NOT NULL
AND #rpmuserTableVariable.usr_id = ru.usr_id
select * from #rpmuserTableVariable
Do I need to use a temp table #tempblah or is there a "trick" to doing this?
Also, I CAN do a bulk update right? I do not need to do a WHILE loop do I?
No need. You just need a table alias. Aliases cannot start with #:
UPDATE rtv
SET STATUS = 1
FROM #rpmuserTableVariable rtv INNER JOIN
rpm_scrty_rpm_usr ru WITH(NOLOCK)
ON rtv.usr_id = ru.usr_id INNER JOIN
rpm_scrty_emp_info ei WITH(NOLOCK)
ON ru.wwid = ei.wwid
WHERE ru.inact_ind = 'N' AND
ei.inact_ind = 'N' AND
ei.dmn_addr IS NOT NULL;

getting wrong results in count function while using group by clause in sql server

im calculating how many links are submitted in each categories. i have assigned four categories -Classifieds,Events,Articles,Socialbookmarking for monday . user submitted 15 links in classified category . but it showing 15*4 = 60 links submitted.
output getting like this
Categoryname DayTarget LnkSubmsnDate LnkSubmtdBy submittedLinks performance
Classifieds 15 10/12/2015 swapna 60 Reached
but i want like this
Categoryname DayTarget LnkSubmsnDate LnkSubmtdBy submittedLinks performance
Classifieds 15 10/12/2015 swapna 15 Reached
Events 2 10/12/2015 swapna 0 not Reached
Articles 2 10/12/2015 swapna 0 not Reached
Socialbookmarking 10 10/12/2015 swapna 0 not Reached
sql query
select c.Categoryname,DayTarget,l.LnkSubmsnDate,l.LnkSubmtdBy,COUNT(LinkId) as submittedLinks,
(CASE
WHEN DayTarget=COUNT(LinkId) THEN 'Reached'
WHEN DayTarget-COUNT(LinkId) < 1 THEN 'Reached'
WHEN DayTarget-COUNT(LinkId) >= 1 THEN 'Not Reached'
END ) as performance
from tbl_Link as l
join Tbl_DaySubmission ds on l.ProjectId=ds.projectid and l.CategoryId=ds.CatId
join tbl_Category c on l.CategoryId=c.CategoryId
where LnkSubmsnDate='2015-10-12'and l.ProjectId='109'
group by c.Categoryname,ds.DayTarget,LnkSubmsnDate,l.LnkSubmtdBy
table definations
TABLE [dbo].[Tbl_DaySubmission](
[DayId] [bigint] IDENTITY(100,1) NOT NULL,
[DayName] [varchar](50) NOT NULL,
[DayNumber] [int] NOT NULL,
[CatId] [int] NULL,
[DayTarget] [int] NOT NULL,
[ProjectID] [int] NULL,
[status] [bit] NULL
tbl_link
TABLE [dbo].[tbl_Link](
[LinkId] [bigint] IDENTITY(1,1) NOT NULL,
[LinkName] [nvarchar](255) NULL,
[ReportLinks] [nvarchar](255) NULL,
[CreatedDate] [nvarchar](255) NULL,
[CategoryId] [int] NULL,
[KeywordID] [int] NULL,
[ProjectId] [int] NULL,
[LnkSubmsnDate] [date] NULL,
[LnkSubmtdBy] [nvarchar](255) NULL,
tbl_category
TABLE [dbo].[tbl_Category](
[CategoryId] [int] IDENTITY(1,1) NOT NULL,
[Categoryname] [varchar](50) NOT NULL
if you are getting answers in multiples of the expected value, it means that your join is not working properly (Data is not as you expected in one of the table).
We cannot guide you without seeing the actual data in all of the tables as you are not using the primary keys to join tables.
I would suggest you to break your query into multiple steps and evaluate the result at each step before joining with another table and that would help you in fixing it.
You can't retrieve LnkSubmsnDate and LnkSubmtdBy from unsubmitted tbl_Links. You have to set default values to the 2 columns if they are unsubmitted, otherwise they show null.
SELECT
c.Categoryname
, ds.DayTarget
, CASE WHEN (COUNT(LinkId) > 0) THEN l.LnkSubmsnDate
ELSE NULL END AS [LnkSubmsnDate]
, CASE WHEN (COUNT(LinkId) > 0) THEN l.LnkSubmtdBy
ELSE NULL END AS [LnkSubmtdBy]
, COUNT(LinkId) AS submittedLinks
, (CASE
WHEN DayTarget=COUNT(LinkId) THEN 'Reached'
WHEN DayTarget-COUNT(LinkId) < 1 THEN 'Reached'
WHEN DayTarget-COUNT(LinkId) >= 1 THEN 'Not Reached'
END ) AS performance
FROM tbl_Category AS c
INNER JOIN Tbl_DaySubmission AS ds ON ds.CatId = c.CategoryId
LEFT JOIN (SELECT * FROM tbl_Link WHERE LnkSubmsnDate='2015-10-12') AS l ON l.ProjectId = ds.ProjectID AND l.CategoryId = ds.CatId
WHERE ds.ProjectID = 109
GROUP BY c.Categoryname, ds.DayTarget, l.LnkSubmsnDate, l.LnkSubmtdBy
ORDER BY performance DESC
http://sqlfiddle.com/#!6/548a26/7

How do I aggregate 3 columns that are different with MIN(DATE)?

I'm facing a simple problem here that I can't solve, I have this query:
SELECT
MIN(TEA_InicioTarefa),
PFJ_Id_Analista,
ATC_Id,
SRV_Id
FROM
dbo.TarefaEtapaAreaTecnica
INNER JOIN Tarefa t ON t.TRF_Id = TarefaEtapaAreaTecnica.TRF_Id
WHERE SRV_Id = 88
GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista
ORDER BY ATC_Id ASC
It returns me this:
I was able to group it a little with GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista that gave me these 8 records, but as you can see some PFJ_Id_Analista are different.
What I want is to select only the early date of each SRV_Id and ATC_Id, the PFJ_Id_Analista don't need to grup, if I remove PFJ_Id_Analista from the grouping the query works, but I need the column.
For eg.: between row number 2 and 3 I want only the early date, so it will be row 2. The same goes for rows 5 to 8, I want only row 6.
DDL for TarefaEtapaAreaTecnica (important key: TRF_Id)
CREATE TABLE [dbo].[TarefaEtapaAreaTecnica](
[TEA_Id] [int] IDENTITY(1,1) NOT NULL,
**[TRF_Id] [int] NOT NULL,**
[ETS_Id] [int] NOT NULL,
[ATC_Id] [int] NOT NULL,
[TEA_Revisao] [int] NOT NULL,
[PFJ_Id_Projetista] [int] NULL,
[TEA_DoctosQtd] [int] NULL,
[TEA_InicioTarefa] [datetime2](7) NULL,
[PFJ_Id_Analista] [int] NULL,
[TEA_FimTarefa] [datetime2](7) NULL,
[TEA_HorasQtd] [numeric](18, 1) NULL,
[TEA_NcfQtd] [int] NULL,
[PAT_Id] [int] NULL
DDL for Tarefa (important keys TRF_Id and SRV_Id (which I need it)):
CREATE TABLE [dbo].[Tarefa](
**[TRF_Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,**
**[SRV_Id] [int] NOT NULL,**
[TRT_Id] [int] NOT NULL,
[TRF_Descr] [varchar](255) NULL,
[TRF_Entrada] [datetime] NOT NULL,
[TRF_DoctosQtd] [int] NOT NULL,
[TRF_Devolucao] [datetime] NULL,
[TRF_NcfQtd] [int] NULL,
[TRF_EhDocInsuf] [bit] NULL,
[TRF_Observ] [varchar](255) NULL,
[TRF_AreasTrfQtd] [int] NULL,
[TRF_AreasTrfLiqQtd] [int] NULL
Thanks a lot.
EDIT:
CORRECT QUERY
Based on #Gordon Linoff post:
select t.TEA_InicioTarefa, t.PFJ_Id_Analista, t.ATC_Id, t.SRV_Id
from (select t.*,
row_number() over (partition by ATC_Id, SRV_Id
order by TEA_InicioTarefa) as seqnum, ta.SRV_Id
from dbo.TarefaEtapaAreaTecnica t
inner join dbo.Tarefa ta on t.TRF_Id = ta.TRF_Id
) t
where seqnum = 1 AND t.SRV_Id = 88
Just use window functions:
select t.*
from (select t.*,
row_number() over (partition by ATC_Id, SRV_Id
order by ini) as seqnum
from dbo.TarefaEtapaAreaTecnica t
) t
where seqnum = 1;
This is really an example of filtering, not aggregation. The problem is getting the right value to filter on.
Then get the grouping first and then do a JOIN with it like
SELECT
x.Min_TEA_InicioTarefa,
t.PFJ_Id_Analista,
t.ATC_Id,
t.SRV_Id
FROM
dbo.TarefaEtapaAreaTecnica t
INNER JOIN Tarefa ta ON ta.TRF_Id = t.TRF_Id
INNER JOIN (
select SRV_Id, MIN(TEA_InicioTarefa) as Min_TEA_InicioTarefa
from dbo.TarefaEtapaAreaTecnica
GROUP BY SRV_Id
) x ON t.SRV_Id = x.SRV_Id
WHERE t.SRV_Id = 88
ORDER BY t.ATC_Id ASC;

Return rows which have same data in three columns

I have a table with the following schema
CREATE TABLE [dbo].[personas](
[id_persona] [int] IDENTITY(1,1) NOT NULL,
[nombres] [nvarchar](50) NOT NULL,
[apellido_paterno] [nvarchar](50) NULL,
[apellido_materno] [nvarchar](50) NULL,
[fecha_nacimiento] [date] NOT NULL,
[sexo] [varchar](1) NOT NULL,
[estado_civil] [nvarchar](50) NOT NULL,
[calle] [nvarchar](200) NULL,
[colonia] [nvarchar](100) NULL,
[codigo_postal] [char](5) NOT NULL,
[telefonos] [varchar](50) NULL,
[celular] [varchar](25) NULL,
[email] [varchar](50) NULL,
)
How do I make a query in SQL Server to return rows where nombre, apellido_paterno and apellido_materno are repeated? I mean two or more rows have the same data in these columns.
I suppose I'm looking something opposite to DISTINCT clause
You would want...
SELECT nombre, apellido_paterno, apellido_materno
FROM dbo.personas
GROUP BY nombre, apellido_paterno, apellido_materno
HAVING COUNT(*) > 1
If you want to look at the actual rows, then use that as an inner query and join onto it. So, something like
SELECT *
FROM personas pOuter INNER JOIN
(SELECT nombre, apellido_paterno, apellido_materno
FROM dbo.personas
GROUP BY nombre, apellido_paterno, apellido_materno
HAVING COUNT(*) > 1) pInner
ON pInner.nombre = pOuter.nombre
AND pInner.apellido_paterno = pOuter.apellido_paterno
AND pInner.apellido_materno = pOuter.apellido_materno
;WITH x AS
(
SELECT id_personas, rn = ROW_NUMBER() OVER
(
PARTITION BY nombre, apellido_paterno, apellido_materno
ORDER BY id_personas
)
FROM dbo.personas
)
SELECT <col list>
FROM dbo.personas AS p
WHERE EXISTS
(
SELECT 1 FROM x
WHERE x.id_personas = p.id_personas
AND x.rn > 1
);