Trying to combine this queries into one, because I want to write queries without using temp table. Keep getting syntax error - sql

SELECT
CAST([patientDATA] AS XML).value('PatientcardCard[1]/Replacements[1]/patientId[1]', 'nvarchar(80)') [patientId]
,* into #tmp
FROM hospital [c1] with(NOLOCK)
where
patientserial in (
select ptserial From patients with(Nolock)
where patientsid=6889
and patientprogramid in (
26917,
21296,
27025
)
)
select patientId,patientbarcode,patientprogramID
into #tmp1
From #tmp
join patients with(nolock) on patientserial=ptserial
where patientid in
('0401478300007847',
'0401478300008566',
'0401478300008761',
'0401478300008727',
'0401478300007648',
'0401478300008020'
)
So first query is using cast to get value from a tag inside a column, the tag is patientID, and it is storing data into a temp table.
The second query is pulling the data from the temp table. I want to write a nested query without using temp table. But I keep syntax error, this is my query so far:
select patientId,patientbarcode,patientprogramID
From (
SELECT
CAST([patientDATA] AS XML).value('PatientcardCard[1]/Replacements[1]/patientId[1]', 'nvarchar(80)') [patientId]
,* into #tmp
FROM hospital [c1] with(NOLOCK)
where
patientserial in (
select ptserial From patients with(Nolock)
where patientsid=6889
and patientprogramid in (
26917,
21296,
27025
)
)
)
join patients with(nolock) on patientserial=ptserial
where patientid in
('0401478300007847',
'0401478300008566',
'0401478300008761',
'0401478300008727',
'0401478300007648',
'0401478300008020'
)
My error in SQL:
invalid column in first line, around patientId,patientbarcode
and in join part, invalid column as ptserial
Is it because the value is casted?

There are some problems with your approach.
SELECT * is not a good idea. It also appears to be unnecessary
for your final query.
You should reference which table each column
is coming from.
You may be overthinking this.
SELECT CAST([patientDATA] AS XML).value('PatientcardCard[1]/Replacements[1]/patientId[1]', 'nvarchar(80)') [patientId]
, patientbarcode
, patiendprogramID
FROM hospital h
INNER JOIN patients p ON p.ptserial = h.patientserial
WHERE patientsid = 6889
AND patientprogramid IN (26917, 21296, 27025)
AND patientid IN (
'0401478300007847'
,'0401478300008566'
,'0401478300008761'
,'0401478300008727'
,'0401478300007648'
,'0401478300008020'
)

Related

SQL How to get full Array in a temporary table with condition?

Well, I am really sorry because my explanation was so poor. Thank you for all the answers.
I will explain better what should be the output and what is my question.
So, first of I have an array of tagCodes like ('code0','code1','code2').
Then I have a table that contains Codes and TagTypeId.
I would like to get into a temporary table all the codes I passed in the array with their TagTypeId. So a table like:
Code
TagTypeId
903420012408181609019A18
2456
903420012408181609019A18
2135
TestCodeNull
null
So my attempt was this one:
SELECT Tags.Code AS tagCode, Tags.TagTypeId, TagTypes.Code AS tagType
INTO #TempTable
FROM Tags JOIN TagTypes ON Tags.TagTypeId = TagTypes.Id
WHERE Tags.Code IN ('903420012408181609019A18','90341808151313061101E938', 'TestCodeNull')
SELECT * FROM #TempTable;
But I dont get the codes that are not in the Tag table.
I did this an it seems to be working as intended:
CREATE TABLE #TestTable (tagCode NVARCHAR(25) NOT NULL, TagTypeId INT NULL, tagType NVARCHAR(MAX))
INSERT INTO #TestTable (tagCode) VALUES ('903420012408181609019A18'),('00007E08190D0A34E1F524D0'),('00007E08190D0B25E1F5A98B')
UPDATE #TestTable SET TagTypeId = Tags.TagTypeId, tagType = TagTypes.Code FROM #TestTable
LEFT JOIN Tags ON (#TestTable.tagCode = Tags.Code)
LEFT JOIN TagTypes ON (Tags.TagTypeId = TagTypes.Id)
SELECT * FROM #TestTable;
I think what you mean that 'TestCodeNull' does not exist in tags so you want to show null for 'TestCodeNull' in which case a join may be more appropriate. for example
SELECT S.CODE,Tags.Code AS tagCode, Tags.TagTypeId,
TagTypes.Code AS tagType
INTO #TempTable
FROM (select '903420012408181609019A18' code
union all select '90341808151313061101E938'
union all select 'TestCodeNull') s
left join Tags on tags.code = s.code
left JOIN TagTypes ON Tags.TagTypeId = TagTypes.Id
SELECT * FROM #TempTable;

Rewrite query without using temp table

I have a query that is using a temp table to insert some data then another select from to extract distinct results. That query by it self was fine but now with entity-framework it is causing all kinds of unexpected errors at the wrong time.
Is there any way I can rewrite the query not to use a temp table? When this is converted into a stored procedure and in entity framework the result set is of type int which throws an error:
Could not find an implementation of the query pattern Select not found.
Here is the query
Drop Table IF EXISTS #Temp
SELECT
a.ReceiverID,
a.AntennaID,
a.AntennaName into #Temp
FROM RFIDReceiverAntenna a
full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID)
where (a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join #Temp t on r.ReceiverID = t.ReceiverID;
No need for anything fancy, you can just replace the reference to #temp with an inner sub-query containing the query that generates #temp e.g.
select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join (
select
a.ReceiverID,
a.AntennaID,
a.AntennaName
from RFIDReceiverAntenna a
full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID)
where (a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
) t on r.ReceiverID = t.ReceiverID;
PS: I haven't made any effort to improve the query overall like Gordon has but do consider his suggestions.
First, a full join makes no sense in the first query. You are selecting only columns from the first table, so you need that.
Second, you can use a CTE.
Third, you should be able to get rid of the SELECT DISTINCT by using an EXISTS condition.
I would suggest:
WITH ra AS (
SELECT ra.*
FROM RFIDReceiverAntenna ra
Station s
ON s.ReceiverID = ra.ReceiverID AND
s.AntennaID = ra.AntennaID)
WHERE s.ReceiverID is NULL
)
SELECT r.ReceiverID, r.ReceiverName, r.receiverdescription
FROM RFIDReceiver r
WHERE EXISTS (SELECT 1
FROM ra
WHERE r.ReceiverID = ra.ReceiverID
);
You can use CTE instead of the temp table:
WITH
CTE
AS
(
SELECT
a.ReceiverID,
a.AntennaID,
a.AntennaName
FROM
RFIDReceiverAntenna a
full join Station b
ON (a.ReceiverID = b.ReceiverID)
and (a.AntennaID = b.AntennaID)
where
(a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
)
select distinct
r.ReceiverID, r.ReceiverName, r.receiverdescription
from
RFIDReceiver r
inner join CTE t on r.ReceiverID = t.ReceiverID
;
This query will return the same results as your original query with the temp table, but its performance may be quite different; not necessarily slower, it can be faster. Just something that you should be aware about.

sql inner table substitution

Suppose I have an sql query like the following (I realize this query could be written better, just bear with me):
SELECT aT.NAME
FROM anothertable aT,
( SELECT ts.slot_id,
tgm.trans_id,
tagm.agent_id
FROM slots ts,
transactions tgm,
agents tagm
WHERE ts.slot_id = (12345, 678910)
and ts.slot_id = tagm.slot_id
AND ts.slot_id = tgm.slot_id) INNER
WHERE INNER.trans_id = aT.trans_id
AND INNER.agent_id = aT.trans_id
Now suppose that I need to break up this query into two parts...in the first I'll execute the inner query, do some processing on the results in code, and then pass back a reduced set to the outer part of the query. The question is, is there an easy way to emulate an inner table in sql?
For instance, if the results of the inner query returned 5 rows but my program deems to only need two of those rows, how can I write sql that will do what I am trying to do below? Is there a way, in sql, to declare a table for in memory in query use?
SELECT
at.Name
FROM
anotherTable aT,
(SLOT_ID, TRANS_ID, AGENT_ID
-------------------------
230743, 3270893, 2307203
078490, 230897, 237021) inner
WHERE
inner.trans_id = at.trans_id
AND INNER.agent_id = aT.trans_id
Just use a subquery:
SELECT at.Name
FROM anotherTable aT JOIN
(select 230743 as SLOT_ID, 3270893 as TRANS_ID, 2307203 as AGENT_ID from dual
select 078490, 230897, 237021 from dual
) i
on i.trans_id = at.trans_id AND i.agent_id = aT.trans_id;
Most systems will let you define a TEMP TABLE or TABLE VARIABLE: https://www.simple-talk.com/sql/t-sql-programming/temporary-tables-in-sql-server/
CREATE TABLE #temp (
SLOT_ID INT,
TRANS_ID INT,
AGENT_ID INT
);
INSERT INTO #temp(SLOT_ID, TRANS_ID, AGENT_ID)
(--inner query goes here)
--do your main query, then:
DROP TABLE #temp
IN MS SQL Server (not sure about other systems), you could possibly use a Common Table Expression (CTE): https://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx
WITH inner AS (
--inner query goes here
)
--main select goes here
Personally, since I generally work with MSSQL Server, I use CTE's quite a bit, as they can be created "on the fly", and can be a big help in organizing more complex queries.
The subquery method worked. Since this is Oracle, the syntax turned out to be:
SELECT aT.Name
FROM anotherTable aT,
(select 1907945 as SLOT_ID, 2732985 as TRANS_ID, 40157 as AGENT_ID FROM DUAL
union
select 1907945, 2732985, 40187 FROM DUAL
) inner
WHERE
inner.trans_id = aT.trans_id AND INNER.agent_id = aT.trans_id;

Query returns a different result every time it is run

This query always returns the same amount of rows but, in a different order, every time. Why does this happen?
I have more filters to add but I can't get past this step.
BEGIN
DECLARE #lastStatus Varchar(10)
SELECT
[Job].[Job],
[Job].[Part_Number],
[Job].[Rev],
[Job_Operation].[Description],
[Job].[Customer_PO],
[Job].[Customer_PO_LN],
[Delivery].[Promised_Date],
[Job_Operation].[Operation_Service],
[Job].[Note_Text],
[Job_Operation].[Status],
[Job_Operation].[Sequence]
INTO [#tmpTbl]
FROM [PRODUCTION].[dbo].[Job_Operation]
INNER JOIN [Job]
ON [Job_Operation].[Job]=[Job].[Job]
INNER JOIN [Delivery]
ON [Job_Operation].[Job]=[Delivery].[Job]
WHERE [Job].[Status]='Complete'
ORDER BY [Job_Operation].[Job],[Job_Operation].[Sequence]
SELECT *
FROM [#tmpTbl]
DROP TABLE [#tmpTbl]
END
Put the Order By on the Select * From #tmpTbl, not on the insert.
Hi you can do initials on your table and you can remove your bracket for non spaces so you can make your code shorter.
SELECT j.Job,
,j.[Part_Number]
,j.Rev
,j_O.Description
,j.Customer_PO
,j.[Customer_PO_LN]
,d.[Promised_Date]
,j_o.[Operation_Service]
,j.[Note_Text],
,j_o.Status,
,j_o.Sequence
,j.[Customer_PO],
,j.[Customer_PO_LN],
,d.[Promised_Date],
,j_o.[Operation_Service],
,j.[Note_Text],
,j_o.[Status],
[Job_Operation].[Sequence]
INTO [#tmpTbl]
FROM [PRODUCTION].[dbo].[Job_Operation] j_o
INNER JOIN Job j
ON j_o.Job = j.Job
INNER JOIN Delivery d
ON j_o.Job= d.Job
WHERE j.Status='Complete'
ORDER BY j_o.Job,j_o.Sequence
SELECT *
FROM [#tmpTbl]
DROP TABLE [#tmpTbl]
END
Because you don't have an order by clause when you select from #tmpTbl
Try
SELECT *
FROM [#tmpTbl]
ORDER BY Job, Sequence
You cannot specify the order data goes into a table through a SET command (i.e. SELECT INTO) - that is determined by whether the table has a clustered index defined after it's created.
You control the order of the data when you're eventually selecting FROM that table to get your results.
SELECT * FROM [#tmpTbl] ORDER BY ....

TSQL Distinct in Select Statement with Joins

I have a query that is providing the correct data to me but if there are multiple records in the tuitionSubmission table for the same empID, it shows duplicate results (as expected).
I am trying to use a distinct selector on this query on A.[empID]
Below is my Query:
SELECT A.[empID],
A.[id],
A.[empGradDate],
A.[status],
A.[reimbursementDate],
A.[firstName],
A.[lastName],
A.[businessTitle] AS department,
B.[SupEmpID],
B.[ntid] AS empNTID,
B.[GeoLocationDesc] AS location,
C.[FirstName] + ' ' + C.[LastName] AS supervisor,
C.[ntid] AS supNTID,
C.[SupEmpID],
D.[FirstName] + ' ' + D.[LastName] AS manager,
D.[ntid] AS managerNTID
FROM tuitionSubmissions AS A
INNER JOIN
empTable AS B
ON A.[empID] = B.[EmpID]
INNER JOIN
empTable AS C
ON C.[empID] = B.[SupEmpID]
INNER JOIN
empTable AS D
ON D.[empID] = C.[SupEmpID]
WHERE
B.[EmpID]= COALESCE(#ntid, B.[EmpID]) OR
B.[SupEmpID]= COALESCE(#supervisor, B.[SupEmpID]) OR
C.[SupEmpID]= COALESCE(#manager, C.[SupEmpID]) OR
A.[EmpID]= COALESCE(#empName, C.[EmpID]) OR
B.[GeoLocationDesc]= COALESCE(#theLocation, B.[GeoLocationDesc]) OR
B.[SiloDesc]= COALESCE(#department, B.[SiloDesc])
FOR XML PATH ('details'), TYPE, ELEMENTS, ROOT ('root');
The table tuitionSubmissions can contain multiple records for the same user (same empID) but I only want to show one of them
The comment:
"I only want to show one of them" which one?– usr
is extremely important, because that's the crux of the issue. If you have duplicates, you need some rule to determine which of two duplicates is correct. If the duplicate rows are 100% identical, then you're missing a Primary Key. (And now you see why they're so important.)
Even if all you do is add a RowId IDENTITY column so that you know which of the duplicates was more recently added, this will go a long way to making your life easier. I'd also suggest you go about removing your duplicates, they're not contributing any information, and simply wasting space. Here's a question asking how to remove duplicates which should help.
However, if you want to hang on to the duplicates, you can complicate your query by removing them "on the fly".
;WITH UniqueSubs AS (
SELECT DISTINCT
[id], [empGradDate], [status], [reimbursementDate],
[firstName], [lastName], [businessTitle], [EmpID]
FROM tuitionSubmissions
)
SELECT A.[empID],
/* ... And the rest of your query as is.
... Just substitute tuitionSubmissions with UniqueSubs.
*/
However, since you have an id column, perhaps you already have that IDENTITY column I mentioned earlier. This can be used as a "uniqueifier" to get the most recent version of tuitionSubmissions per EmpID as follows:
;WITH RecentSubs AS (
SELECT EmpID, MAX(id) AS MaxID
FROM tuitionSubmissions
),
UniqueSubs AS (
SELECT ts.*
FROM RecentSubs rs
INNER JOIN tuitionSubmissions ts ON
ts.id = rs.id
/*Prev join condition should suffice, but add if needed*/
--AND ts.EmpID = rs.EmpID
)
SELECT A.[empID],
/* ... And the rest of your query as is.
... Just substitute tuitionSubmissions with UniqueSubs.
*/
You can get what you want by adding the last part below to your where clause
WHERE
(B.[EmpID]= COALESCE(#ntid, B.[EmpID]) OR
B.[SupEmpID]= COALESCE(#supervisor, B.[SupEmpID]) OR
C.[SupEmpID]= COALESCE(#manager, C.[SupEmpID]) OR
A.[EmpID]= COALESCE(#empName, C.[EmpID]) OR
B.[GeoLocationDesc]= COALESCE(#theLocation, B.[GeoLocationDesc]) OR
B.[SiloDesc]= COALESCE(#department, B.[SiloDesc]))
AND A.[id] IN
(SELECT MAX(AMax.id)
FROM tuitionSubmissions AS AMax
GROUP BY AMax.empID)