How can I insert data into a temporary table - tsql

Is there a way to insert the results of this query into a temporary table in SSMS? I have tried a number of ways but failed thus far.
Or is there another way, all I al looking for it to query the results of this and join another table which I can't seem to do in the query itself.
USE CommDB
;With CTE AS (SELECT s.attendanceNumber,
MAX(CASE WHEN s.rnk = 1 THEN s.ExamExaminationCode END) as examCode1,
MAX(CASE WHEN s.rnk = 2 THEN s.ExamExaminationCode END) as examCode2,
MAX(CASE WHEN s.rnk = 3 THEN s.ExamExaminationCode END) as examCode3,
MAX(CASE WHEN s.rnk = 4 THEN s.ExamExaminationCode END) as examCode4,
MAX(CASE WHEN s.rnk = 5 THEN s.ExamExaminationCode END) as examCode5,
MAX(CASE WHEN s.rnk = 6 THEN s.ExamExaminationCode END) as examCode6,
MAX(CASE WHEN s.rnk = 7 THEN s.ExamExaminationCode END) as examCode7,
MAX(CASE WHEN s.rnk = 8 THEN s.ExamExaminationCode END) as examCode8,
MAX(CASE WHEN s.rnk = 9 THEN s.ExamExaminationCode END) as examCode9,
MAX(CASE WHEN s.rnk = 10 THEN s.ExamExaminationCode END) as examCode10,
MAX(CASE WHEN s.rnk = 11 THEN s.ExamExaminationCode END) as examCode11,
MAX(CASE WHEN s.rnk = 12 THEN s.ExamExaminationCode END) as examCode12,
MAX(CASE WHEN s.rnk = 13 THEN s.ExamExaminationCode END) as examCode13,
MAX(CASE WHEN s.rnk = 14 THEN s.ExamExaminationCode END) as examCode14
FROM (
SELECT [AttendanceNumber]
,[ExaminationDate]
,RadiologyID
,[ExamExaminationCode]
,ROW_NUMBER() OVER(PARTITION BY [AttendanceNumber]
ORDER BY [ExamExaminationCode]) as rnk --Ordered ASC so examcodes dont move
FROM [CommDB].[dbo].[tblRadiologyData] rd
where rd.ExaminationDate >= '01 october 2015'
and rd.AttendanceSiteCode IN('CNM','RNM') ) s
GROUP BY s.attendanceNumber)
Select c.examCode1,
c.examCode2,
c.examCode3,
c.examCode4,
c.examCode5,
c.examCode6,
c.examCode7,
c.examCode8,
c.examCode9,
c.examCode10,
c.examCode11,
c.examCode12,
c.examCode13,
c.examCode14,
c.AttendanceNumber,
COUNT(c.AttendanceNumber) as [No of occurances]
-- (Select lu.HRGCode from CommDB.dbo.tblRadiologyNucMedLookup lu
-- Where ISNULL(c.examCode1,'') = ISNULL(lu.Exam01,'')
-- )
from CTE c
GROUP by c.examCode1,
c.examCode2,
C.examCode3,
C.examCode4,
C.examCode5,
C.examCode6,
C.examCode7,
C.examCode8,
C.examCode9,
C.examCode10,
C.examCode11,
C.examCode12,
C.examCode13,
C.examCode14,
C.AttendanceNumber
ORDER BY C.examCode1

With pivot statement your live will be much easier - you don't need cte.
And your question - there are several types of temporary tables:
global temporary table - prefixed with ## (you can access this table from other sessions)
session temporary table - prefixed with # (you can access this table only from session)
variable temporary - must be declared and prefixed with # (you can access this table only in one batch)
table on tempdb - common table, but after administration tasks (restart service) will be deleted
other:
you can use view or TVF instead of temporary tables (it is another way)
you can utilize potencial of CTE (most people use it only as view)
Type 1,2,4 you can create as standard table (with create statement or script select into).
Type 3 you have to declare as variable.
Example of session temporary table:
create table #TmpTable (id int, col1 varchar(5), col2 varchar(5))
insert into #TmpTable (id, col1, col2) select 1, 'KSDFA', 'ASDAS' -- from tbl

Related

Pivot for multiple columns in SQL Server

I have 3 areas:
Melt, HSM, LSM
each order produced in some areas with following data:
Start Date, Finish Date, Weight
I have a Viewin SQL Server 2012(top image), How can I create a pivot that generate bottom image, using tsql?
You could use conditional aggregation:
SELECT [Order],
MAX(CASE WHEN Area = 'Melt' THEN StartDate END) AS Melt_SDate,
MAX(CASE WHEN Area = 'Melt' THEN FinisthDate END) AS Melt_FDate,
MAX(CASE WHEN Area = 'Melt' THEN Weight END) AS Melt_Weight,
MAX(CASE WHEN Area = 'HSM' THEN StartDate END) AS HSM_SDate,
MAX(CASE WHEN Area = 'HSM' THEN FinisthDa END) AS HSM_FDate,
MAX(CASE WHEN Area = 'HSM' THEN Weight END) AS HSM_Weight,
MAX(CASE WHEN Area = 'LSM' THEN StartDate END) AS LSM_SDate,
MAX(CASE WHEN Area = 'LSM' THEN FinisthDate END) AS LSM_FDate,
MAX(CASE WHEN Area = 'LSM' THEN Weight END) AS LSM_Weight
FROM tab_name
GROUP BY [Order]; -- ORDER is reserved word, you should avoid such identifiers;
To make it more concise you could use IIF:
MAX(CASE WHEN Area = 'Melt' THEN StartDate END) AS Melt_SDate,
<=>
MAX(IIF(Area='Melt',StartDate,NULL)) AS Melt_SDate,

Using Where clause in between Inner Join Query

I am looking to fetch records and I have come through a scenario in which i have to include additional where clauses between the select query using inner join.
select stp.sales_person as "Sales_Person",
max(case when stp.jan_month is null then 0 else stp.jan_month end) as "January",
select sum(so.amount_total) from sale_order so inner join res_users ru on ru.id=so.user_id
where date(so.confirmation_date) > '2017-01-01' and date(so.confirmation_date) < '2017-01-30',
max(case when stp.feb_month is null then 0 else stp.feb_month end) as "February",
max(case when stp.march_month is null then 0 else stp.march_month end) as "March",
max(case when stp.dec_month is null then 0 else stp.dec_month end) as "December"
from sales_target_record stp
inner join res_partner rp on rp.name=stp.sales_person inner join res_users ru on ru.partner_id = rp.id inner join crm_team ct on ru.sale_team_id = ct.id
where ct.name = 'Direct Sales' group by stp.sales_person
I have to insert columns like i tried with sum but is not working as its a join query
You have a syntax issue in your query if this is truly SQL Server
select
stp.sales_person as Sales_Person,
max(case
when stp.jan_month is null
then 0
else stp.jan_month
end) as January,
--This needed parenthese since it's a subquery. Though, it's uncorrelated
( select sum(so.amount_total)
from sale_order so
inner join res_users ru on ru.id=so.user_id
where cast(so.confirmation_date as date) > '2017-01-01' and cast(so.confirmation_date as date) < '2017-01-30'
--here you need to add something like stp.someColumn = so.SomeColumn to correlate it to the outer query
) as SomeNewColumnUnCorrelated,
max(case
when stp.feb_month is null
then 0
else stp.feb_month
end) as February,
max(case
when stp.march_month is null
then 0
else stp.march_month
end) as March,
max(case
when stp.dec_month is null
then 0
else stp.dec_month
end) as December
from
sales_target_record stp
inner join
res_partner rp on
rp.name=stp.sales_person
inner join
res_users ru on
ru.partner_id = rp.id
where
ct.name = 'Direct Sales'
group by
stp.sales_person

How to use an Alias in a Calculation for Another Field

Does anybody know if there is a way to replicate the method used in this question of using the alias of a sub query to perform calculations on another field in t- SQL?
I tried using the same syntax for the following query in MS SQL Express and got the error below:
DECLARE #PracticeID INT
DECLARE #Date1 date
DECLARE #Date2 date
SET #PracticeID = 11015
SET #Date1 = '2017-06-01'
SET #Date2 = '2017-09-01'
SELECT prtc.PracticeName ,COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,
COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
( SELECT COUNT(*)
FROM UserEvent UE
WHERE UE.EventTypeID = 1 AND
UE.PracticeID = au.PracticeID AND
(UE.EventDate BETWEEN #Date1 and #Date2)
) TotalNumberLogins,
(SELECT TotalNumberofLogins) - ((SELECT iOSLogins) + (SELECT AndroidLogins )) DesktopLogins
FROM UserDeviceInfo UDI JOIN
AppUser AU ON udi.UserID = au.UserID JOIN
Practice PRTC ON au.PracticeID = prtc.PracticeID
WHERE au.PracticeID = #PracticeID AND
(udi.Created BETWEEN #Date1 AND #Date2)
GROUP BY prtc.PracticeName, au.PracticeID
Msg 207, Level 16, State 1, Line 17 Invalid column name
'TotalNumberofLogins'. Msg 207, Level 16, State 1, Line 17 Invalid
column name 'iOSLogins'. Msg 207, Level 16, State 1, Line 17 Invalid
column name 'AndroidLogins'.
Not that it would make a difference, but I did try putting the alias's in quotes and brackets to no avail.
I did manage to get the desired result from another method by performing the calculations using the same values as variables instead of alias's and then inserting them into a table.
That query is however, verbose and I would like to know if there is any way of replicating the behavior in the referenced question for future use.
Thank you for any help you can provide.
That method doesn't work in SQL Server. You can accomplish the same thing in a couple different ways:
1.) Use the code for each aliased column instead of the alias:
(SELECT COUNT(*)
FROM UserEvent UE
WHERE UE.EventTypeID = 1
AND UE.PracticeID = au.PracticeID
AND (UE.EventDate BETWEEN #Date1 and #Date2)
- COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END)
+ COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) Desktop Logics
2.) Use a derived table to make the columns, then you can reference them by alias:
SELECT PracticeName, iOSLogins, AndroidLogins, TotalNumberLogins,
(TotalNumberofLogins - (iOSLogins + AndroidLogins)) DesktopLogins
FROM (
SELECT prtc.PracticeName,
COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,
COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
( SELECT COUNT(*)
FROM UserEvent UE
WHERE UE.EventTypeID = 1
AND UE.PracticeID = au.PracticeID
AND (UE.EventDate BETWEEN #Date1 and #Date2)
) TotalNumberLogins,
FROM UserDeviceInfo UDI
JOIN AppUser AU ON udi.UserID = au.UserID
JOIN Practice PRTC ON au.PracticeID = prtc.PracticeID
WHERE au.PracticeID = #PracticeID
AND (udi.Created BETWEEN #Date1 AND #Date2)
GROUP BY prtc.PracticeName, au.PracticeID
) a --table alias
Edit: Table alias explained
In a simple query:
SELECT col1 FROM Table
You know the table reference for col1 is Table. (Table.Col1) You don't have to write it if it is the only col1, but you still know the table it is referencing.
In a simple derived table:
SELECT col1 FROM (SELECT col1 FROM Table)
The table reference for the inner column is still Table, but what about the outer? In this case, everything within the parentheses is your table, but in the above example that table is unnamed. SQL Server requires that you name/alias the table that you have created so you can reference it:
SELECT col1 FROM (SELECT col1 FROM Table) MyDerivedTable
...and now you have a table reference for your outer column:
SELECT MyDerivedTable.col1 FROM (SELECT col1 FROM Table) MyDerivedTable
You can also see a greater need for this once more tables are involved:
SELECT MyDerivedTable.col1
FROM (SELECT col1 FROM Table) MyDerivedTable
JOIN Table T on T.col1 = MyDerivedTable.col1
Edit 2: CTE option:
Another option is a common table expression or CTE:
with cteName as (
SELECT prtc.PracticeName,
COUNT(CASE WHEN udi.DevicePlatform = 'iOS' THEN 1 ELSE NULL END) iOSLogins,
COUNT(CASE WHEN udi.DevicePlatform = 'Android' THEN 1 ELSE NULL END) AndroidLogins,
( SELECT COUNT(*)
FROM UserEvent UE
WHERE UE.EventTypeID = 1
AND UE.PracticeID = au.PracticeID
AND (UE.EventDate BETWEEN #Date1 and #Date2)
) TotalNumberLogins,
FROM UserDeviceInfo UDI
JOIN AppUser AU ON udi.UserID = au.UserID
JOIN Practice PRTC ON au.PracticeID = prtc.PracticeID
WHERE au.PracticeID = #PracticeID
AND (udi.Created BETWEEN #Date1 AND #Date2)
GROUP BY prtc.PracticeName, au.PracticeID
)
SELECT PracticeName, iOSLogins, AndroidLogins, TotalNumberLogins,
(TotalNumberofLogins - (iOSLogins + AndroidLogins)) DesktopLogins
FROM cteName
These can be pretty convenient because they create a clear separation between the outer and inner queries. Ultimately it does the same thing as inline derived tables, so choose whichever version is more readable to you. (props to xorcus for suggesting the CTE addition)

convert rows into column in db2

I need the below select results to be converted into single row ,
Actual output:
ORDER POSTCODE Quantity Value
123456 AAAAA 22.78 5
123456 AAAAA 2.93 7
Expected Output:
ORDER POSTCODE AmbientQuantity Ambientvalue FVQuantity FvVAlue
123456 AAAAA 22.78 5 2.93 7
How to achieve the expected output in db2?
Following SQL will do the job:
with temp as (
select ORDER, POSTCODE, QUANTITY, VALUE,
rownumber() over (partition by ORDER, POSTCODE) as rownum
FROM mytable2
)
select ORDER, POSTCODE,
max(case when rownum = 1 Then QUANTITY end) as AMBIENTQUANTITY,
max(case when rownum = 1 Then VALUE end) as AMBIENTVALUE,
max(case when rownum = 2 Then QUANTITY end) as FVQuantity,
max(case when rownum = 2 Then VALUE end) as FVVALUE
from temp
group by ORDER, POSTCODE
Try something like this:
with tmp as (
select f0.*, rownumber() over(partition by f0.ORDER, f0.POSTCODE) rang
from your table f0
)
select
f1.ORDER, f1.POSTCODE, f1.Quantity AmbientQuantity, f1.Value Ambientvalue,
f2.Quantity FVQuantity2, f2.Value FvVAlue2,
f3.Quantity FVQuantity3, f2.Value FvVAlue3,
f4.Quantity FVQuantity4, f2.Value FvVAlue4
from tmp f1
left outer join tmp f2 on (f1.ORDER, f1.POSTCODE)=(f2.ORDER, f2.POSTCODE) and f2.rang=2
left outer join tmp f3 on (f1.ORDER, f1.POSTCODE)=(f3.ORDER, f3.POSTCODE) and f3.rang=3
left outer join tmp f4 on (f1.ORDER, f1.POSTCODE)=(f4.ORDER, f4.POSTCODE) and f4.rang=4
where f1.rang=1

Help with difficult 'group by' clause

need some your help with a query.
I have a table Managers (ManagerId, ManagerName)
I have a table Statuses (StatusId, StatusName)
(There's about 10 statuses in that table)
I have a table Clients (ClientId, ClientName, ManagerId, StatusId, WhenAdded)
(WhenAdded is a datetime type)
It's obvious that field 'ManagerId' refers to a table 'Managers' and field 'StatusId' refers to a table 'Statuses'.
User wants to get some statistics about Managers over a period of time (from startDate to endDate using field 'WhenAdded') in the following table.
Columns:
ManagerName, NumberOfClients, NumberOfClientsWithStatus1, NumberOfClientsWithStatus2, NumberOfClientsWithStatus3 and so on.
Number of columns with name NumberOfClientsWithStatusI where i is a number of statuses equal to number of rows in table 'Statuses'.
How can I do that?
t-sql, sql server 2008 r2 express edition.
SELECT
ManagerName,
COUNT(*) AS NumberOfClients,
COUNT(CASE WHEN S.StatusId = 1 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus1,
COUNT(CASE WHEN S.StatusId = 2 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus2,
COUNT(CASE WHEN S.StatusId = 3 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus3,
...
FROM
Clients C
JOIN
Managers M ON C.ManagerId = M.ManagerId
JOIN
Statuses S ON C.StatusId = S.StatusId
WHERE
M.WhenAdded BETWEEN #startDate AND #endDate
GROUP BY
M.ManagerName
Note: there is no clean way to add arbritrary numbers of status columns in SQL (not just SQL Server) because its a fixed column output. You'd have to change the query for status, unless you deal with this in the client
Edit, after comment
SELECT
ManagerName,
COUNT(*) AS NumberOfClients,
COUNT(CASE WHEN S.StatusId = 1 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus1,
COUNT(CASE WHEN S.StatusId = 2 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus2,
COUNT(CASE WHEN S.StatusId = 3 THEN 1 ELSE NULL END) AS NumberOfClientsWithStatus3,
...
FROM
Managers M ON C.ManagerId = M.ManagerId
LEFT JOIN
Clients C
LEFT JOIN
Statuses S ON C.StatusId = S.StatusId
WHERE
M.WhenAdded BETWEEN #startDate AND #endDate
GROUP BY
M.ManagerName
If you know that statuses table will always contain a limited number of statuses, you can do this:
SELECT M.ManagerName,
COUNT(C.ClientId) NumberOfClients,
SUM(CASE WHEN S.StatusId= 1 THEN 1 ELSE 0 END) NumberOfClientsWithStatus1,
SUM(CASE WHEN S.StatusId= 2 THEN 1 ELSE 0 END) NumberOfClientsWithStatus2,
...
FROM Clients C
JOIN Managers M on M.ManagerId = C.ManagerId
JOIN Statuses S on S.StatusId = C.StatusId
WHERE C.WhenAdded BETWEEN startDate AND endDate
GROUP BY ManagerName