I have a SQL Server query that I am attempting to port to MySQL, but the JOIN syntax is something that I have never seen used before. The query is from a view designed to measure procedure code usage. What the heck is going on with the JOIN syntax just past T.PatID = P.ID, and the third LEFT OUTER JOIN, and what equivalent syntax can we use in MySQL? It does not like this JOIN syntax at all (disregard the ISNULL and CONVERT SQL Server specific syntax)
SELECT
T.Code
, P.LastName
, P.FirstName
, T.TranDate
, CD.DaysUnits
, T.TranAmt
, TD.FullName AS Provider
, ISNULL(TD.ID, ISNULL(AD.ID, PD.ID)) AS DoctorID
FROM
dbo.Doctors AS PD
INNER JOIN
dbo.Transactions AS T
INNER JOIN
dbo.Patients AS P
ON
T.PatID = P.ID
ON
PD.ID = P.DoctorID
LEFT OUTER JOIN
dbo.Doctors AS TD
ON
T.DoctorID = TD.ID
LEFT OUTER JOIN
dbo.Doctors AS AD
LEFT OUTER JOIN
dbo.Appointments
ON
AD.ID = dbo.Appointments.DoctorID
AND CONVERT(varchar(20), dbo.Appointments.ScheduleDateTime, 8) <> '00:00:00'
ON
T.ApptID = dbo.Appointments.ID
LEFT OUTER JOIN
dbo.ChargeDetails AS CD
ON
T.ID = CD.ChargeTranID
WHERE
(
T.Code IS NOT NULL
)
The SHOW CREATE TABLE are as follows
CREATE TABLE Doctors
(
ID int(10) NOT NULL PRIMARY KEY
, FullName varchar(50) DEFAULT NULL
)
CREATE TABLE Patients
(
LName varchar(50) DEFAULT NULL
, FName varchar(50) DEFAULT NULL
, ID int(10) NOT NULL PRIMARY KEY
)
CREATE TABLE Transactions
(
TranType varchar(2) DEFAULT NULL
, Code varchar(100) DEFAULT NULL
, TranSubType varchar(2) DEFAULT NULL
, Description varchar(2000) DEFAULT NULL
, TranDate datetime
, PatID int(10) DEFAULT NULL
, ID int(10) NOT NULL PRIMARY KEY
, TranAmt decimal(19,4) DEFAULT NULL
, ApptID int(10) DEFAULT NULL
, DoctorID int(10) DEFAULT NULL
)
CREATE TABLE ChargeDetails
(
DaysUnits varchar(50) DEFAULT NULL
-- DaysUnits is just an int ranging from 1 to 2
, ChargeTranID int(10) NOT NULL PRIMARY KEY
)
CREATE TABLE Appointments
(
DoctorID int(10) DEFAULT NULL
, PatientID int(10) DEFAULT NULL
, ScheduleDateTime datetime DEFAULT NULL
, ID int(10) NOT NULL PRIMARY KEY
)
Thank you in advance for your help.
Here is a similar (and simplified) query using the same structure as the first query. The second query moves the joins around to make things easier to read.
set nocount on;
use tempdb;
go
declare #doc table (id int not null);
declare #tran table (id int not null, patid int not null);
declare #patients table (id int not null, docid int not null);
insert #doc (id) values (1);
insert #patients (id, docid) values (25, 1);
insert #tran (id, patid) values (100, 25)
select *
from #doc as pd
inner join #tran as t
inner join #patients as p
on t.patid = p.id
on pd.id = p.docid;
select *
from #tran as t
inner join #patients as p
on t.patid = p.id
inner join #doc as pd
on pd.id = p.docid;
Other things look strange. I don't see a need to join to appointments but I'm not going to spend a lot of time to figure out the logic and the schema. The convert usage seems like a bad way to check for null - unless there is a special "flag" datetime value that is used as the equivalent to null. Again, you need to understand the query, the goal of the query, the schema on which it is based, and how the tables are populated. Quite frankly, this code raises concerns about the quality of the entire system.
.
Related
I have two tables 1) a customer table 2)Account table. I want to see what accounts are primary and which are secondary accounts.
In one table I have accountRowId. In the other table I have PrimaryAccountRowId and SecondaryAccountRowId and ‘AccountNumber’.
For my output I would like to have all AccountNumbers in one column with all the AccountRelationship(primary or seconday) in another column beside each AccountNumber.
In order to join table, for PrimaryAccounts I would join AccountRowId on PrimaryAccountRowId and for secondary Accounts I would just flip flop and instead of having the primaryAccountRowId it would be SecondaryAccountRowId.
My Account table:
AccountRowId = 256073
AccountRowId = 342300
Customer table:
PrimaryAccountRowId = 256073
SecondaryAccountRowId = 342300
AccountNumber = 8003564
AccountNumber = 2034666
What I want to see my table look like
AccoundNumber AccountRelationship
8003564 Primary
2034666 Secondary
Please provide some helpful logic/code of how I would achieve these results.
From the OP's comments here is the table structure.
Create table Customer
(
AccountNumber Varchar(50)
, PrimaryAccountRowId Varchar(15)
, SecondaryAccountRowId Varchar(15)
);
Create table Account
(
AccountRowId Varchar(15)
);
I am still somewhat guessing here. You need to provide table structure, sample data and desired output to make it easy for people to help you. Something along these lines.
declare #Customer table
(
AccountNumber Varchar(50)
, PrimaryAccountRowId Varchar(15)
, SecondaryAccountRowId Varchar(15)
)
insert #Customer values
('8003564', '256073', null)
, ('2034666', null, '342300')
declare #Account table
(
AccountRowid Varchar(15)
)
INSERT #Account values
('256073'), ('342300')
Now that we have some tables and data to work with this just becomes a case of conditional aggregation. This should return the data you are looking for as I understand the need.
select c.AccountNumber
, AccountRelationship = max(case when p.AccountRowId is not null then 'Primary' when c.SecondaryAccountRowId is not null then 'Secondary' end)
from #Customer c
left join #Account p on p.AccountRowid = c.PrimaryAccountRowId
left join #Account s on s.AccountRowid = c.SecondaryAccountRowId
group by c.AccountNumber
order by AccountRelationship
What I'm trying to achieve is a data set where by I have a set of holdings data against its benchmark and show where the holdings are either on or off benchmark. The data set should look like this:
PositionDate PortfolioCode Benchmark SecurityDesciption PortfolioWeight BenchmarkWeight
2017-03-31 Port1 JPM Sec1 1.00 1.5
2017-03-31 Port1 JPM Sec2 0.54 NULL
2017-03-31 Port1 JPM Sec3 NULL 0.5
My SQL currently looks like the following with a FULL OUTER JOIN so that you can return weights from both the portfolio data and the benchmark data depending on whether the portfolio holds it or not:
SELECT
lt.PositionDate AS PositionDate
, lt.PortfolioCode AS PortfolioCode
, gpi.indx_desc AS Benchmark
, i.iss_desc AS SecurityDescription
, lt.BaseCCYEffectiveExposure / NULLIF(lt.TOTALPortfolioMV_BaseCcy,0) AS PortfolioWeight
, issindx.WGHT_EOD AS BenchmarkWeight
FROM #Lkthru AS lt
INNER JOIN ISSUE_DG AS i
ON i.INSTR_ID = lt.ID_NETIK_INSTR_ID
INNER JOIN GP_BNCHMRK_XREF AS bxref -- Portfolio Benchmark Crossreference
ON bxref.acct_id = lt.portfoliocode -- Links to Portfolio
AND bxref.bnchmrk_type = 'Primary' -- Link to reporting benchmark
AND (#EndDate BETWEEN bxref.start_tms AND ISNULL(bxref.end_tms,#EndDate)) -- Ensures you pick up the correct benchmark for the date you are reporting for
INNER JOIN gp_index AS gpi
ON gpi.indx_id = bxref.indx_id -- Links to GP_INDEX to pick up the correct benchmark
FULL OUTER JOIN iss_indx_cnstnt AS issindx -- Join to ensure we have all constituents of benchmark returned as well as all portfolio constituents
ON issindx.indx_instr_id = gpi.INSTR_ID
AND issindx.cnstnt_instr_id = i.instr_id -- Join to constituents of portfolio
AND issindx.as_of_dte = #EndDate
However I'm not returning the desired result set and I seem to be getting every record from ISS_INDX_CNSNT returned. It must be something to do with the filters after the ON on my FULL OUTER JOIN or its just not possible to do what I'm trying to achieve? I'm trying to avoid having to put the filtered data into a temp table and then join or creating a UNION ALL and then GROUP BY.
Does anyone have an ideas as to where I'm going wrong?
EDIT - included working example
DECLARE #EndDate DATETIME
SET #EndDate = '2017-03-31'
DECLARE #Port TABLE
(
PortCode VARCHAR(40)
)
INSERT INTO #Port VALUES ('Port1')
DECLARE #Lkthru TABLE
(
PositionDate DATETIME
, PortfolioCode VARCHAR(40)
, Instr_ID VARCHAR(40)
, PortfolioWeight FLOAT
)
INSERT INTO #Lkthru VALUES('2017-03-31','Port1','1',1.00)
INSERT INTO #Lkthru VALUES('2017-03-31','Port1','2',0.54)
DECLARE #Issue_DG TABLE
(
Instr_ID VARCHAR(40)
, SecurityDesc VARCHAR(100)
)
INSERT INTO #Issue_DG VALUES ('1','Sec1')
INSERT INTO #Issue_DG VALUES ('2','Sec2')
INSERT INTO #Issue_DG VALUES ('3','Sec3')
INSERT INTO #Issue_DG VALUES ('4','Sec4')
DECLARE #GP_BNCHRK_XREF TABLE
(
PortfolioCode VARCHAR(40)
, BenchmarkID VARCHAR(40)
)
INSERT INTO #GP_BNCHRK_XREF VALUES ('Port1','JPM1')
DECLARE #GPIndex TABLE
(
BenchmarkID VARCHAR(40)
, BenchmarkNme VARCHAR(40)
)
INSERT INTO #GPIndex VALUES ('JPM1','JPM')
DECLARE #IssueIndexConst TABLE
(
BenchmarkDate DATETIME
, BenchmarkID VARCHAR(40)
, Const_ID VARCHAR(40)
, BenchmarkWeight FLOAT
)
INSERT INTO #IssueIndexConst VALUES ('2017-03-31','JPM1','1',1.5)
INSERT INTO #IssueIndexConst VALUES ('2017-03-31','JPM1','3',0.5)
INSERT INTO #IssueIndexConst VALUES ('2017-03-31','JPM1','4',0.5)
INSERT INTO #IssueIndexConst VALUES ('2017-02-28','JPM1','1',1.5)
INSERT INTO #IssueIndexConst VALUES ('2017-02-28','JPM1','3',0.5)
INSERT INTO #IssueIndexConst VALUES ('2017-02-28','JPM1','4',0.5)
SELECT
ISNULL(lt.PositionDate,issindx.BenchmarkDate) AS PositionDate
, ISNULL(lt.PortfolioCode,bxref2.PortfolioCode) AS PortfolioCode
, ISNULL(gpi.BenchmarkNme,gpi2.BenchmarkNme) AS Benchmark
, ISNULL(i.SecurityDesc,ib.SecurityDesc) AS SecurityDesc
, lt.PortfolioWeight
, issindx.BenchmarkWeight
FROM #GP_BNCHRK_XREF AS bxref
INNER JOIN #Lkthru AS lt
ON lt.PortfolioCode = bxref.PortfolioCode
INNER JOIN #Issue_DG AS i
ON i.Instr_ID = lt.Instr_ID
INNER JOIN #GPIndex AS gpi
ON gpi.BenchmarkID = bxref.BenchmarkID
FULL OUTER JOIN #IssueIndexConst AS issindx
ON issindx.BenchmarkID = gpi.BenchmarkID
AND issindx.Const_ID = i.Instr_ID
AND issindx.BenchmarkDate = #EndDate
LEFT OUTER JOIN #Issue_DG AS ib
ON ib.Instr_ID = issindx.Const_ID
LEFT OUTER JOIN #GPIndex AS gpi2
ON gpi2.BenchmarkID = issindx.BenchmarkID
LEFT OUTER JOIN #GP_BNCHRK_XREF AS bxref2
ON bxref2.BenchmarkID = issindx.BenchmarkID
i'm trying to insert data from one table to another with dynamic column name from #array to #array2
error
The multi-part identifier "s.id" could not be bound.
SQL CODE:
DECLARE #Array TABLE
(
id int not null,
dt varchar(12) not null,
ld varchar(16) not null,
val varchar(12) not null,
ty varchar(4) not null,
PRIMARY KEY CLUSTERED (id,dt)
)
DECLARE #Array2 TABLE
(
id int not null,
dt varchar(12) not null,
ld varchar(16) not null,
min varchar(12) null,
mout varchar(4) null,
PRIMARY KEY CLUSTERED (id,dt)
)
INSERT INTO #Array VALUES
('1','2015-11-11','2015-11-11','20:08','min')
,('2','2015-11-11','2015-11-11','20:08','mout')
,('3','2015-11-11','2015-11-11','20:08','min')
,('4','2015-11-11','2015-11-11','20:08','min')
Select * from #Array s
WHERE NOT EXISTS (select s.id,s.dt,s.ld,s.ty from #Array2
WHERE id != s.id AND dt != s.dt)
INSERT INTO #Array2 (id,dt,ld,s.ty) VALUES(s.id,s.dt,s.ld,s.val)
^
dynamic column name from #Array TABLE
here is SQL Fiddle link, thanks.
I would re-write your insert along the lines of:
INSERT INTO #Array2 (id,dt,ld,s.ty)
Select s.id,s.dt,s.ld,s.ty from #Array s
left join #Array2 a2 on a2.id = s.id
where a2.id is null
Your error is coming from the fact that Array2 doesn't have a ty column defined. The fix there is to either put it in there or re-evaluate what you are putting into it. Also, thumbs up for the fiddle link :)
EDIT:
On second reading of your question, do you want to dynamically add that column to array2? If so, then that would require quite a bit of mucking around, and I would try to find another solution. Changing your schema like that on the fly is ill-advised.
EDIT2:
INSERT INTO #Array2 (id,dt,ld,min,mout)
Select
s.id,
s.dt,
s.ld,
case s.ty when 'min' then s.val else '' end,
case s.ty when 'mout' then s.val else '' end
from #Array s
left join #Array2 a2 on a2.id = s.id
where a2.id is null
EDIT3
UPDATE a2
SET
a2.dt = s.dt,
a2.ld = s.ld,
a2.min = case s.ty when 'min' then s.val else '' end,
a2.mout = case s.ty when 'mout' then s.val else '' END
FROM #Array2 a2
LEFT JOIN #Array s ON a2.id = s.id
WHERE s.id IS NOT null
I'm designing a simple in-office ticket system, and would like to include a field for the party responsible for the next action. To do so right this moment I'm thinking of using tableName and tableID as specifiers for the specific responsible party (could be a technician, customer, or third party, all in different tables)
It would be fine to pull that data in and run another select call using the name of the table as a parameter, but the extra data flow slows things down significantly.
Is there a way to use a single join statement to return the details of the party with a column for the table name and one for the individual table id or is there a better way to store the data from multiple potential tables?
You can use left join to achieve your requirement :-
Set Nocount On;
Declare #OfficeTickets Table
(
Id Int Identity(1,1)
,Column1 Varchar(100)
,PartyType Varchar(1)
,TechnicianId Int Null
,CustomerId Int Null
,ThirdPartyId Int Null
)
Declare #OfficeTickets1 Table
(
Id Int Identity(1,1)
,Column1 Varchar(100)
,TableName Varchar(100)
,TableId Int Null
)
Declare #Technician Table
(
Id Int Identity(1,1)
,TechnicianName Varchar(100)
)
Declare #Customers Table
(
Id Int Identity(1,1)
,CustomerName Varchar(100)
)
Declare #ThirdParty Table
(
Id Int Identity(1,1)
,ThirdPartyName Varchar(100)
)
Insert Into #Technician(TechnicianName) Values
('Technician_1')
,('Technician_2')
,('Technician_3')
Insert Into #Customers(CustomerName) Values
('Customer_1')
,('Customer_2')
,('Customer_3')
Insert Into #ThirdParty(ThirdPartyName) Values
('ThirdParty_1')
,('ThirdParty_2')
,('ThirdParty_3')
,('ThirdParty_4')
Insert Into #OfficeTickets(Column1,PartyType,TechnicianId,CustomerId,ThirdPartyId) Values
('ABC','T',3,Null,Null)
,('XYZ','C',Null,2,Null)
,('PUQ','P',Null,Null,4)
Insert Into #OfficeTickets1(Column1,TableName,TableId) Values
('ABC','Technician',3)
,('XYZ','Customers',2)
,('PUQ','ThirdParty',4)
---- taken separate columns for parties
Select ot.Id
,ot.Column1
,t.TechnicianName
,c.CustomerName
,tp.ThirdPartyName
From #OfficeTickets As ot
Left Join #Technician As t On ot.PartyType = 'T' And ot.TechnicianId = t.Id
Left Join #Customers As c On ot.PartyType = 'C' And ot.CustomerId = c.Id
Left Join #ThirdParty As tp On ot.PartyType = 'P' And ot.ThirdPartyId = tp.Id
---- by TableName and TableId
Select ot.Id
,ot.Column1
,t.TechnicianName
,c.CustomerName
,tp.ThirdPartyName
From #OfficeTickets1 As ot
Left Join #Technician As t On ot.TableName = 'Technician' And ot.TableId = t.Id
Left Join #Customers As c On ot.TableName = 'Customers' And ot.TableId = c.Id
Left Join #ThirdParty As tp On ot.TableName = 'ThirdParty' And ot.TableId = tp.Id
output:-
I have to select values from three tables. First table is sale_project_detail, the second table is design_project_detail, and the third table is design_designer.
sale_project_detail schema:
Id int,
Name nvarchar(50),
ShortDescription nvarchar(max)
design_project_assignment schema:
Id int,
DId int (It is foreign key of design_designer table),
SPId int (It is foreign key of sale_project_detail table),
AssignDateTime datetime,
DueDate date,
Status varchar(10)
design_designer schema:
Id int,
Name nvarchar(15)
Now, I have to select complete detail from sale_project_detail
where assign_project_detail.SPId <> sale_project_detail.Id,
and
Select design_designer(Name)
from design_designer
where design_designer.Id = assign_project_detail.DId
I am trying below code, but it is returning wrong result.
My code:
SELECT
sale_project_detail.*,
design_project_assignment.*,
design_designer.Name
FROM
sale_project_detail,
design_project_assignment,
design_designer
WHERE
NOT EXISTS(SELECT NULL
FROM design_project_assignment
LEFT JOIN design_designer ON design_designer.Id = design_project_assignment.DId
WHERE sale_project_detail.Id = design_project_assignment.SPId)
Thanks in advance.
Try this
SELECT
*
FROM
sale_project_detail as spd
inner join design_project_assignment dpa on dpa.spid <> spd.id
inner join design_designer dd on dd.id = dpa.did;