SQL converting CSV text to Table - sql

I have a table with a list of customer orders (s84_Schedule). I have a second table with comments on the orders (s84_ScheduleNotes). When I pull the list of orders from s84_Schedule, I do a left outer join to get the latest comment from s84_ScheduleNotes, because there are not always comments on every order.
Problem: I also have a SQL function that converts a comma-separated list of ProductIDs into a temporary table; this function does not seem to be working properly. I do not understand how these are related, but... If I use only one Product ID (meaning, no comma in the ProductVal variable), the left outer join never pulls in the latest comment from s84_ScheduleNotes. However, if I provide 2 ProductIDs separated by commas in ProductVal, the latest comment will show up.
Here is the code that converts the CSV to a temp table (stole this off the internet somewhere a long time ago)...
CREATE FUNCTION [dbo].[CSVToTable] (#InStr VARCHAR(MAX))
RETURNS #TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET #InStr = REPLACE(#InStr + ',', ',,', ',')
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%,%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #TempTab(id) VALUES (#VALUE)
END
RETURN
END
GO
Here is my procedure which pulls the orders and the comments...
CREATE PROCEDURE dbo.GetFilteredSchedule
(
#InstallDateOperator INT,
#InstallDateRange1 DATETIME,
#InstallDateRange2 DATETIME,
#InstallDateDynRange1 INT,
#InstallDateDynRange2 INT,
#CustExpectedOperator INT,
#CustExpectedRange1 DATETIME,
#CustExpectedRange2 DATETIME,
#CustExpectedDynRange1 INT,
#CustExpectedDynRange2 INT,
#CompletedDateOperator INT,
#CompletedDateRange1 DATETIME,
#CompletedDateRange2 DATETIME,
#CompletedDateDynRange1 INT,
#CompletedDateDynRange2 INT,
#ProdInStoreDateOperator INT,
#ProdInStoreDateRange1 DATETIME,
#ProdInStoreDateRange2 DATETIME,
#ProdInStoreDateDynRange1 INT,
#ProdInStoreDateDynRange2 INT,
#InvoiceNumVal VARCHAR(2000),
#InstallerVal VARCHAR(2000),
#CustomerVal VARCHAR(2000),
#SubdivisionVal VARCHAR(2000),
#ProductVal VARCHAR(2000),
#LotNumVal VARCHAR(2000),
#EstimateNumVal VARCHAR(2000),
#SONumVal VARCHAR(2000),
#ProdInStoreVal BIT,
#OrderProcessedVal BIT,
#StatusVal VARCHAR(2000),
#FieldRepVal VARCHAR(2000),
#WorkOrderNumVal VARCHAR(2000),
#WindowVal VARCHAR(2000),
#StoreVal VARCHAR(2000),
#DriverVal VARCHAR(2000),
#YardEmployeeVal VARCHAR(2000),
#TruckTypeVal VARCHAR(2000),
#LotNumExact INT,
#StatusIDExact INT,
#SearchText VARCHAR(2000),
#CustomerIdRestriction VARCHAR(2000),
#OrderBy1 INT,
#OrderBy2 INT
)
AS
BEGIN
SELECT sch.ScheduleID, sch.InstallDate, sch.CustomerExpectedDate, sch.CompletedDate, sch.InvoiceNumber,
sch.InstallerID, sch.CustomerID, sch.SubdivisionID, sch.ProductID, sch.LotNumber, sch.EstimateNumber, sch.SONumber,
sch.ProductInStore, sch.ProductInStoreDate, sch.OrderProcessed, sch.HomeownerInfo, sch.StatusID, sch.FieldRepID,
sch.WindowID, sch.StoreID, sch.ConnectedToProject, sch.DriverEmailAddress, sch.YardEmployeeEmailAddress, sch.TruckTypeID,
installer.InstallerName AS 'InstallerName',
customer.CustomerName AS 'CustomerName',
subdivision.SubdivisionName AS 'SubdivisionName',
product.ProductName AS 'ProductName',
fieldRep.FieldRepName AS 'FieldRepName',
window.WindowName AS 'WindowName',
store.StoreName AS 'StoreName',
stat.StatusName AS 'StatusName',
driver.LastName AS 'DriverLastName', driver.FirstName AS 'DriverFirstName',
yardEmployee.LastName AS 'YardEmployeeLastName', yardEmployee.FirstName AS 'YardEmployeeFirstName',
truckType.TruckTypeName AS 'TruckTypeName',
sch.ScheduleID AS id,
Cast(customer.CustomerName AS VARCHAR(2000)) + ' - ' + Cast(sch.LotNumber AS VARCHAR(2000)) + ' - ' + Cast(subdivision.SubdivisionName AS VARCHAR(2000)) + ' - ' + Cast(product.ProductName AS VARCHAR(2000)) AS 'title',
CONVERT(VARCHAR(50), sch.CustomerExpectedDate, 101) + ' ' + CONVERT(VARCHAR, DATEPART(hh, sch.CustomerExpectedDate)) + ':' + RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, sch.CustomerExpectedDate)), 2) AS 'start',
CONVERT(VARCHAR(50), DATEADD(hh, 1, sch.CustomerExpectedDate), 101) AS 'end',
stat.StatusColor AS 'backgroundColor',
note.NoteText AS 'NoteText'
FROM s84_Schedule sch
LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)
JOIN dbo.s84_Installer AS installer ON sch.InstallerID = installer.InstallerID
JOIN dbo.s84_Customer AS customer on sch.CustomerID = customer.CustomerID
JOIN dbo.s84_Subdivision AS subdivision ON sch.SubdivisionID = subdivision.SubdivisionID
JOIN dbo.s84_Product AS product ON sch.ProductID = product.ProductID
JOIN dbo.s84_FieldRep AS fieldRep ON sch.FieldRepID = fieldRep.FieldRepID
JOIN dbo.s84_Window AS window ON sch.WindowID = window.WindowID
JOIN dbo.s84_Store AS store ON sch.StoreID = store.StoreID
JOIN dbo.s84_Status AS stat ON sch.StatusID = stat.StatusID
JOIN dbo.s84_TruckType AS truckType ON sch.TruckTypeID = truckType.TruckTypeID
LEFT OUTER JOIN dbo.s84_Employee AS driver ON ((#DriverVal IS NOT NULL) AND (driver.EmailAddress = #DriverVal))
LEFT OUTER JOIN dbo.s84_Employee AS yardEmployee ON ((#YardEmployeeVal IS NOT NULL) AND (yardEmployee.EmailAddress = #YardEmployeeVal))
WHERE
(#InvoiceNumVal IS NULL OR (sch.InvoiceNumber LIKE '%' + #InvoiceNumVal + '%')) AND
(#InstallerVal IS NULL OR (installer.InstallerID = #InstallerVal)) AND
(#CustomerVal IS NULL OR (customer.CustomerName LIKE '%' + #CustomerVal + '%')) AND
(#SubdivisionVal IS NULL OR (subdivision.SubdivisionName LIKE '%' + #SubdivisionVal + '%')) AND
(#ProductVal IS NULL OR ( sch.ProductID IN (SELECT * FROM dbo.CSVToTable(#ProductVal)) )) AND
(#LotNumVal IS NULL OR (sch.LotNumber LIKE '%' + #LotNumVal + '%')) AND
(#EstimateNumVal IS NULL OR (sch.EstimateNumber LIKE '%' + #EstimateNumVal + '%')) AND
(#SONumVal IS NULL OR (sch.SONumber LIKE '%' + #SONumVal + '%')) AND
(#ProdInStoreVal IS NULL OR (sch.ProductInStore = #ProdInStoreVal)) AND
(#OrderProcessedVal IS NULL OR (sch.OrderProcessed = #OrderProcessedVal)) AND
(#FieldRepVal IS NULL OR (fieldRep.FieldRepID = #FieldRepVal)) AND
(#WorkOrderNumVal IS NULL OR (sch.ScheduleID LIKE '%' + #WorkOrderNumVal + '%')) AND
(#WindowVal IS NULL OR (window.WindowName LIKE '%' + #WindowVal + '%')) AND
(#StoreVal IS NULL OR (store.StoreName LIKE '%' + #StoreVal + '%')) AND
(#DriverVal IS NULL OR ((driver.FirstName LIKE '%' + #DriverVal + '%') OR (driver.LastName LIKE '%' + #DriverVal + '%'))) AND
(#YardEmployeeVal IS NULL OR ((yardEmployee.FirstName LIKE '%' + #YardEmployeeVal + '%') OR (yardEmployee.LastName LIKE '%' + #YardEmployeeVal + '%'))) AND
(#TruckTypeVal IS NULL OR (truckType.TruckTypeName LIKE '%' + #TruckTypeVal + '%')) AND
(#LotNumExact IS NULL OR (sch.LotNumber = #LotNumExact)) AND
(#StatusIDExact IS NULL OR (sch.StatusID = #StatusIDExact)) AND
(#CustomerIdRestriction IS NULL OR ( sch.CustomerID IN (SELECT * FROM dbo.CSVToTable(#CustomerIdRestriction)) )) AND
(#StatusVal IS NULL OR
( sch.StatusID IN (SELECT * FROM dbo.CSVToTable(#StatusVal)) OR
(
('9999' IN (SELECT * FROM dbo.CSVToTable(#StatusVal)) ) AND
( sch.StatusID NOT IN (SELECT * FROM (VALUES ('1'), ('2'), ('3'), ('4')) AS X(id)) )
)
)
) AND
(((#InstallDateOperator IS NULL) OR (#InstallDateOperator = 99)) OR
(#InstallDateOperator = 1 AND sch.InstallDate = #InstallDateRange1) OR
(#InstallDateOperator = 2 AND sch.InstallDate <= #InstallDateRange1) OR
(#InstallDateOperator = 3 AND sch.InstallDate >= #InstallDateRange1) OR
(#InstallDateOperator = 4 AND sch.InstallDate >= #InstallDateRange1 AND sch.InstallDate <= #InstallDateRange2) OR
(#InstallDateOperator = 5 AND sch.InstallDate BETWEEN DATEADD(mm,-#InstallDateDynRange1,GETDATE()) AND DATEADD(mm,#InstallDateDynRange2,GETDATE()))
) AND
(((#CustExpectedOperator IS NULL) OR (#CustExpectedOperator = 99)) OR
(#CustExpectedOperator = 1 AND sch.CustomerExpectedDate = #CustExpectedRange1) OR
(#CustExpectedOperator = 2 AND sch.CustomerExpectedDate <= #CustExpectedRange1) OR
(#CustExpectedOperator = 3 AND sch.CustomerExpectedDate >= #CustExpectedRange1) OR
(#CustExpectedOperator = 4 AND sch.CustomerExpectedDate >= #CustExpectedRange1 AND sch.CustomerExpectedDate <= #CustExpectedRange2) OR
(#CustExpectedOperator = 5 AND sch.CustomerExpectedDate BETWEEN DATEADD(mm,-#CustExpectedDynRange1,GETDATE()) AND DATEADD(mm,#CustExpectedDynRange2,GETDATE()))
) AND
(((#CompletedDateOperator IS NULL) OR (#CompletedDateOperator = 99)) OR
(#CompletedDateOperator = 1 AND sch.CompletedDate = #CompletedDateRange1) OR
(#CompletedDateOperator = 2 AND sch.CompletedDate <= #CompletedDateRange1) OR
(#CompletedDateOperator = 3 AND sch.CompletedDate >= #CompletedDateRange1) OR
(#CompletedDateOperator = 4 AND sch.CompletedDate >= #CompletedDateRange1 AND sch.CompletedDate <= #CompletedDateRange2) OR
(#CompletedDateOperator = 5 AND sch.CompletedDate BETWEEN DATEADD(mm,-#CompletedDateDynRange1,GETDATE()) AND DATEADD(mm,#CompletedDateDynRange2,GETDATE()))
) AND
(((#ProdInStoreDateOperator IS NULL) OR (#ProdInStoreDateOperator = 99)) OR
(#ProdInStoreDateOperator = 1 AND sch.ProductInStoreDate = #ProdInStoreDateRange1) OR
(#ProdInStoreDateOperator = 2 AND sch.ProductInStoreDate <= #ProdInStoreDateRange1) OR
(#ProdInStoreDateOperator = 3 AND sch.ProductInStoreDate >= #ProdInStoreDateRange1) OR
(#ProdInStoreDateOperator = 4 AND sch.ProductInStoreDate >= #ProdInStoreDateRange1 AND sch.ProductInStoreDate <= #ProdInStoreDateRange2) OR
(#ProdInStoreDateOperator = 5 AND sch.ProductInStoreDate BETWEEN DATEADD(mm,-#ProdInStoreDateDynRange1,GETDATE()) AND DATEADD(mm,#ProdInStoreDateDynRange2,GETDATE()))
) AND
((#SearchText IS NULL) OR
( sch.InvoiceNumber LIKE '%' + #SearchText + '%' OR
installer.InstallerName LIKE '%' + #SearchText + '%' OR
customer.CustomerName LIKE '%' + #SearchText + '%' OR
subdivision.SubdivisionName LIKE '%' + #SearchText + '%' OR
product.ProductName LIKE '%' + #SearchText + '%' OR
sch.LotNumber LIKE '%' + #SearchText + '%' OR
sch.EstimateNumber LIKE '%' + #SearchText + '%' OR
sch.SONumber LIKE '%' + #SearchText + '%' OR
stat.StatusName LIKE '%' + #SearchText + '%' OR
fieldRep.FieldRepName LIKE '%' + #SearchText + '%' OR
sch.ScheduleID LIKE '%' + #SearchText + '%' OR
window.WindowName LIKE '%' + #SearchText + '%' OR
store.StoreName LIKE '%' + #SearchText + '%'
))
ORDER BY
CASE #OrderBy2
WHEN 1 THEN sch.InstallDate
WHEN 2 THEN sch.CustomerExpectedDate
WHEN 3 THEN sch.CustomerExpectedDate
WHEN 4 THEN sch.CompletedDate
WHEN 5 THEN sch.InvoiceNumber
WHEN 6 THEN installer.InstallerName
WHEN 7 THEN customer.CustomerName
WHEN 8 THEN subdivision.SubdivisionName
WHEN 9 THEN product.ProductName
WHEN 10 THEN sch.LotNumber
WHEN 11 THEN sch.EstimateNumber
WHEN 12 THEN sch.SONumber
WHEN 13 THEN sch.ProductInStore
WHEN 14 THEN sch.ProductInStoreDate
WHEN 15 THEN sch.OrderProcessed
WHEN 16 THEN stat.StatusName
WHEN 17 THEN fieldRep.FieldRepName
WHEN 18 THEN window.WindowName
WHEN 19 THEN store.StoreName
WHEN 20 THEN driver.LastName
WHEN 21 THEN yardEmployee.LastName
ELSE sch.CustomerExpectedDate
END,
CASE #OrderBy1
WHEN 1 THEN sch.InstallDate
WHEN 2 THEN sch.CustomerExpectedDate
WHEN 3 THEN sch.CustomerExpectedDate
WHEN 4 THEN sch.CompletedDate
WHEN 5 THEN sch.InvoiceNumber
WHEN 6 THEN installer.InstallerName
WHEN 7 THEN customer.CustomerName
WHEN 8 THEN subdivision.SubdivisionName
WHEN 9 THEN product.ProductName
WHEN 10 THEN sch.LotNumber
WHEN 11 THEN sch.EstimateNumber
WHEN 12 THEN sch.SONumber
WHEN 13 THEN sch.ProductInStore
WHEN 14 THEN sch.ProductInStoreDate
WHEN 15 THEN sch.OrderProcessed
WHEN 16 THEN stat.StatusName
WHEN 17 THEN fieldRep.FieldRepName
WHEN 18 THEN window.WindowName
WHEN 19 THEN store.StoreName
WHEN 20 THEN driver.LastName
WHEN 21 THEN yardEmployee.LastName
ELSE sch.CustomerExpectedDate
END;
END;
GO
When I provide values to the dbo.GetFilteredSchedule Procedure, these are the vars I set...
I set ProductVal to "26"
I set StatusVal to "1,3,4,9999"
I set OrderBy1 and OrderBy2 to "3"
Everything else is NULL
Here's a print screen of what my table looks like...

This looks wrong:
LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note
ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)
I believe note.ScheduleID should be note.ScheduleNoteID

Related

How to compare data from multiple databases

I'm trying to compare some data from different multiple databases, as I have illustrate my current case, I have there databases, database 1 is the main, and time to time database 2 and database 3 are updated from database 1. I have some difficulties to get the final result which return the data from database 1 and two columns column show the availability in database 2 as Yes or No, and the same with second extra column that will indicate the data availability on the database 3 with Yes or NO.
SELECT *
FROM (
Select ID as db1_ID,
First_name as db1_First_name,
Last_name as db1_Last_name,
Email as db1_Email,
Password as db1_Password,
Request_Id as db1_Request_Id,
User_Id as db1_User_Id,
Request_name as db1_Request_name
from User
inner join User_request
on User_request.User_Id = user.ID
) AS DB1_VIEW
LEFT OUTER JOIN
(
Select ID as db2_ID,
First_name as db2_First_name,
Last_name as db2_Last_name,
Email as db2_Email,
Password as db2_Password,
Request_Id as db2_Request_Id,
User_Id as db2_User_Id,
Request_name as db2_Request_name
from User
inner join User_request
on User_request.User_Id = user.ID
) AS DB2_VIEW
ON db2_ID = db1_ID
LEFT OUTER JOIN
(
Select ID as db3_ID,
First_name as db3_First_name,
Last_name as db3_Last_name,
Email as db3_Email,
Password as db3_Password,
Request_Id as db3_Request_Id,
User_Id as db3_User_Id,
Request_name as db3_Request_name
from User
inner join User_request
on User_request.User_Id = user.ID
) AS DB3_VIEW
ON db3_ID = db1_ID
ID First_name Last_name Email Password Request_Id User_Id Request_name
1 Oliver Jake OJake#domain.com 123 1 1 Request1
2 Mathew Harry MHarry#domain.com 123 1 2 Request1
3 Jacob Reece JReece#domain.com 123 1 3
Request1
4 Charlie Damian CDamian#domain.com 123 1 4 Request1
Use this as your first select statement:
SELECT DB1_VIEW.*
,CASE WHEN DB2_VIEW.db2_ID IS NOT NULL THEN 'Y' ELSE 'N' END AS Available_db2
,CASE WHEN DB3_VIEW.db3_ID IS NOT NULL THEN 'Y' ELSE 'N' END AS Available_db3
You can remove all the details apart from the ID fields in the db2_view and db3_view subqueries.
You can use the below query before execute you should use replace [SourceDB] to your source database and [TargertDB] to your target database. Insert the table name into #mdtables to include for comparison.
USE [SourceDB]
IF Object_id('tempdb..#mdTables') IS NOT NULL
DROP TABLE #mdtables;
CREATE TABLE #mdtables
(
id INT IDENTITY(1, 1) NOT NULL,
schemaname NVARCHAR(128),
tablename NVARCHAR(128)
);
INSERT INTO #mdtables
(schemaname,
tablename)
VALUES ('dbo',
'user');
DECLARE #mdTableLim INT =0,
#mdTableRowId INT =0
SELECT #mdTableLim = Count(*)
FROM #mdtables;
SET #mdTableRowId = 1;
WHILE #mdTableRowId <= #mdTableLim
BEGIN
DECLARE #SDBName VARCHAR(50) = '[SourceDB]',
#TDBName VARCHAR(50) = '[TargertDB]',
#tableName VARCHAR(100) = ''
DECLARE #WhereF VARCHAR(max) ='',
#joincondition VARCHAR(max) ='',
#or VARCHAR(10) ='',
#select VARCHAR(max) = '',
#comma VARCHAR(1)='',
#query VARCHAR(max) ='',
#and VARCHAR(5)='',
#where1 VARCHAR(1000) ='',
#wOR VARCHAR(5)=''
SELECT #tableName = tablename
FROM #mdtables
WHERE id = #mdTableRowId;
SELECT #joincondition += Isnull(#and + ( CASE
WHEN cu.column_name IS NULL
THEN
NULL
ELSE ' src.[' + cu.column_name
+
'] = ' +
'trgt.['
+ c.column_name + ']'
END ), ''),
#WhereF += Isnull (#or + ( CASE
WHEN cu.column_name IS NOT NULL THEN
NULL
ELSE Isnull ( ' src.[' +
TC.column_name
+
'] ',
' isnull( src.[' +
C.column_name +
'],1) ' )
+ Isnull( '<> trgt.[' +
TC.column_name
+ ']',
' = isnull (src.['
+
C.column_name + '],1) ')
END ), ''),
#or = ( CASE
WHEN cu.column_name IS NOT NULL THEN ''
ELSE ' OR '
END ),
#and = ( CASE
WHEN cu.column_name IS NULL THEN ''
ELSE ' AND '
END ),
#select += #comma + ' src.[' + c.column_name + '] '
+ Isnull (' , trgt.[' + TC.column_name + ']', ''),
#comma = ',',
#where1 += Isnull(( #wOR + ( CASE
WHEN cu.column_name IS NULL THEN
NULL
ELSE ' trgt.[' + cu.column_name +
'] is null '
END ) ), ''),
#wOR = ( CASE
WHEN cu.column_name IS NULL THEN ''
ELSE ' OR '
END )
FROM information_schema.columns C
LEFT JOIN information_schema.key_column_usage CU
ON C.column_name = cu.column_name
AND constraint_name LIKE 'PK_%'
AND c.table_name = cu.table_name
LEFT JOIN [TargertDB].information_schema.columns TC
ON C.column_name = TC.column_name
AND c.table_name = TC.table_name
WHERE c.table_name = #tableName
--AND columnproperty(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 0
AND c.column_name NOT IN ( 'LST_CHG_TMS', 'LST_CHG_TMS',
'LST_CHG_USR_ID'
,
'LST_CHG_USR_ID' )
AND c.data_type NOT IN ( 'image' )
ORDER BY cu.column_name
SET #query = 'select ' + #select + ' from ' + #SDBName + '.dbo.'
+ #tableName + ' as src left join ' + #TDBName
+ '.dbo.' + #tableName + ' as trgt on '
+ #joincondition + ' where (' + #where1 + ')'
+ Isnull ('and '+ NULLIF (#WhereF, ''), '')
DECLARE #qu1 VARCHAR(max) =
' declare #cnt int =0 select #cnt =count (1) from '
+ #SDBName + '.dbo.' + #tableName
+ ' as src left join ' + #TDBName + '.dbo.'
+ #tableName + ' as trgt on ' + #joincondition
+ ' where (' + #where1 + ')'
+ Isnull (' OR '+ NULLIF (#WhereF, ''), '')
+ ' if (#cnt>0) begin select '''
+ #tableName + ''' as [ ],#cnt ' +-- #query + ' end '
BEGIN try
EXECUTE ( #qu1)
END try
BEGIN catch
PRINT #qu1;
END catch
SET #mdTableRowId = #mdTableRowId + 1
END
This might not need CTE's or sub-queries.
A few joins might do it.
SELECT
Usr1.ID AS db1_User_Id,
Usr1.First_name AS db1_First_name,
Usr1.Last_name AS db1_Last_name,
Usr1.Email AS db1_Email,
Usr1.Password AS db1_Password,
MAX(UsrReq1.Request_Id) AS db1_Request_Id,
MAX(UsrReq1.Request_name) AS db1_Request_name,
CASE WHEN COUNT(UsrReq2.User_Id) > 0 THEN 'Y' ELSE 'N' END AS Available_Db2,
CASE WHEN COUNT(UsrReq3.User_Id) > 0 THEN 'Y' ELSE 'N' END AS Available_Db3
FROM [Database1].[User] AS Usr1
LEFT JOIN [Database1].[User_request] AS UsrReq1 ON UsrReq1.User_Id = Usr1.ID
LEFT JOIN [Database2].[User] AS Usr2 ON Usr2.ID = Usr1.ID
LEFT JOIN [Database2].[User_request] AS UsrReq2 ON UsrReq2.User_Id = Usr2.ID
LEFT JOIN [Database3].[User] AS Usr3 ON Usr3.ID = Usr1.ID
LEFT JOIN [Database3].[User_request] AS UsrReq3 ON UsrReq3.User_Id = Usr3.ID
GROUP BY
Usr1.ID,
Usr1.First_name,
Usr1.Last_name,
Usr1.Email,
Usr1.Password;

Case with Like operator

Got stuck at using CASE statement with LIKE operator. In the below stored procedure all the parameters are not mandatory so when User doesn't enter PatientName for searching then the below query doesn't return expected results as the LIKE operator is outside which is obvious. I'm looking for something like this so that when User doesn't enter PatientName it will be
(c.LastName + c.Firstname) = #PatientNAme else
(c.LastName + c.Firstname) like '%' + #PatientNAme + '%'
*
(c.LastName + c.Firstname) (
CASE #PatientName
WHEN '' THEN #PatientName = (c.LastName + c.Firstname)
ELSE like '%' + #PatientName + '%'
END
)
*
CREATE proc [dbo].[SearchParkPrescriptionDetails]
#DispenseID INT,
#ParkPrescriptionReasonId INT,
#PrescriptionParkType VARCHAR(50),
#PatientName VARCHAR(120),
#User VARCHAR(120),
#fromdate DATETIME,
#todate DATETIME,
#DateWiseSearch VARCHAR(3),
#PatientID INT
AS
BEGIN
SELECT
a.ParkPrescriptionId
, a.DispenseID
, a.ParkPrescriptionReasonId
, a.ParkDate
, (c.LastName + ' ' + c.Firstname) AS PatientName
, d.PrescriptionType
, e.ParkPrescriptionReason
, a.Notes
, b.ItemCount AS TotalItems
, g.ExemptionReason
,a.[User]
FROM
ParkPrescriptionDetails a
INNER JOIN
Dis_DispenseMaster b
ON
a.DispenseID=b.DispenseID
INNER JOIN
Patient c
ON
b.PatientId = c.PatientId
INNER JOIN
Lookup_PrescriptionType d
ON
b.PrescriptionTypeId = d.PrescriptionTypeId
INNER JOIN
Lookup_ParkPrescriptionReason e
ON
a.ParkPrescriptionReasonId = e.ParkPrescriptionReasonId
LEFT JOIN
Lookup_ExemptionReason g
ON
b.ExemptionReasonId = g.ExemptionReasonId
WHERE
CONVERT(DATE, a.ParkDate) BETWEEN #fromdate AND #todate
AND a.RecallStatus = 'N'
AND a.DispenseID = ( CASE #DispenseID WHEN 0 THEN a.DispenseID ELSE #DispenseID END )
AND b.PatientId = ( CASE #PatientID WHEN 0 THEN b.PatientId ELSE #PatientID END )
AND a.ParkPrescriptionReasonId = ( CASE #ParkPrescriptionReasonId WHEN 0 THEN a.ParkPrescriptionReasonId ELSE #ParkPrescriptionReasonId END )
AND
(
c.LastName + c.Firstname
) LIKE ( CASE #PatientName WHEN '' THEN (c.LastName + c.Firstname) ELSE '%' + #PatientName + '%' END )
AND a.[User] LIKE ( CASE #User WHEN '' THEN a.[User] ELSE '%' + #User + '%' END )
AND b.ParkPrescription = ( CASE #PrescriptionParkType WHEN '' THEN b.ParkPrescription WHEN 'Park' THEN 'Y' END )
AND b.RecallPrescription = ( CASE #PrescriptionParkType WHEN '' THEN b.RecallPrescription WHEN 'Recall' THEN 'Y' END )
AND a.IsDeleted =0
END
========== Changed it Like this. Is this perfect ===========
(c.LastName + ' ' + c.Firstname) = (
CASE #PatientName
WHEN '' THEN (c.LastName + ' ' + c.Firstname)
ELSE '%' + #PatientName + '%'
END
)
Do not use CASE WHEN in where clause. Use OR
(
#PatientName = '' OR
(c.LastName + c.Firstname) LIKE '%' + #PatientName + '%'
) AND
(
#User = '' OR
a.[User] LIKE '%' + #User + '%'
) -- Same for others
instead of
(c.LastName + ' ' + c.Firstname) = (
CASE #PatientName
WHEN '' THEN (c.LastName + ' ' + c.Firstname)
ELSE '%' + #PatientName + '%'
END
)
T-SQL has two forms of CASE. You are using "Simple Case". Try "Searched Case" - e.g.:
CASE
WHEN #PatientName = '' THEN [ return something ]
WHEN #PatientName like [ pattern ] THEN [ return something ]
ELSE [ return something else ]
END

PostgreSQL Create new table out of rows

I am using PostgreSQL 9.1
I have the following table containing some settings
setting | content
---------------+---------
enabled | True
reenable_time | 1
count_row | 6
count_col | 3
(4 rows)
And I want to have something like this
enabled | reenable_time | count_row | count_col
---------+-----------------+-------------+----------
True | 1 | 6 | 3
(1 row)
Thank you for your answers!
What you need is cross-tabulation (pivoting), aka turning rows into columns.
If you don't want to hardcode "enabled", "reenable_time", etc., you need to use dynamic SQL.
The basic idea goes like this:
SELECT -- Grab the user_account columns.
acc.id,
acc.email,
-- Use max() combined with a case statement to
-- usher individual attribute values into columns.
max(CASE WHEN (attr.attribute_type = 'first-name')
THEN attr.value END) AS fname,
max(CASE WHEN (attr.attribute_type = 'last-name')
THEN attr.value END) AS lname,
max(CASE WHEN (attr.attribute_type = 'title')
THEN attr.value END) AS title
FROM user_account AS acc
-- Join the attribute table /once/.
LEFT JOIN user_attribute AS attr
ON (attr.user_account_id = acc.id)
WHERE (acc.email = 'foo#example.com')
-- Group by the non-pivoted columns
GROUP BY acc.id,acc.email;
Here a link for further information:
https://sykosomatic.org/2011/09/pivot-tables-in-postgresql/
Here an example from my workplace (it's MS-SQL, but you'll get the idea, PostGre doesn't support the pivot command, it's MS proprietary, so you need to use "case when" with "group by"):
-- ===================================================
-- Author: Stefan Steiger
-- Create date: 14.04.2011
-- Last modified: 17.01.2012
-- Description: Übersetzung für Berichte
-- ===================================================
CREATE PROCEDURE [dbo].[sp_RPT_Report_Translation]
#in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
AS
BEGIN
DECLARE
#strSQL NVARCHAR(MAX)
,#strReportName NVARCHAR(1000)
,#strPivotColumns NVARCHAR(MAX)
,#stichtag DATETIME
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
SET #stichtag = CONVERT(DATETIME, #in_stichtag)
SET #stichtag = CAST(FLOOR(CAST(#stichtag AS Float)) AS DateTime)
SET #in_stichtag = CONVERT(varchar(50), #stichtag)
SET NOCOUNT ON;
SET #strReportName = REPLACE(#in_report_name, N'''', '''''')
-- http://geekswithblogs.net/baskibv/archive/2008/07/03/123567.aspx
SELECT
#strPivotColumns = COALESCE(#strPivotColumns, '') + '[' + [RTR_ItemCaption] + '], '
FROM T_RPT_Translations
WHERE (RTR_Status = 1)
AND (RTR_MDT_ID = #in_mandant)
AND
(
(RTR_ReportName = #strReportName)
OR
(RTR_ReportName = 'PARA_ALL')
)
--AND (RTR_ItemCaption != 'RPT_Title')
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '')
ORDER BY RTR_Sort
SET #strPivotColumns = SUBSTRING(#strPivotColumns, 0, LEN(#strPivotColumns))
SET #strPivotColumns = REPLACE(#strPivotColumns, N'''', '''''')
--PRINT #strPivotColumns
SET #strSQL = '
SELECT TOP(1) * FROM
(
SELECT
RTR_ItemCaption
--,RTR_Kurz_' + #in_sprache + '
,RTR_Lang_' + #in_sprache + '
FROM T_RPT_Translations
WHERE (RTR_MDT_ID = ''' + #in_mandant+ ''')
AND
(
(RTR_ReportName = ''' + #strReportName + ''')
OR
(RTR_ReportName = ''PARA_ALL'')
)
--AND (RTR_ItemCaption != ''RPT_Title'')
AND (RTR_Status = 1)
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '''')
) AS SourceTable
PIVOT
(
MAX(RTR_Lang_' + #in_sprache + ')
FOR RTR_ItemCaption IN
( '
+ #strPivotColumns +
' )
) AS PivotTable
--ORDER BY RPT_RM_SO_Bezeichnung, RPT_RM_GB_Bezeichnung, RPT_RM_NutzungGruppeCode
'
DECLARE #ProzedurParameter nvarchar(max)
SET #ProzedurParameter = '
DECLARE #in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
;
SET #in_mandant = ''' + REPLACE(#in_mandant, '''', '''''') + ''';
SET #in_sprache = ''' + REPLACE(#in_sprache, '''', '''''') + ''';
SET #in_stichtag = ''' + REPLACE(#in_stichtag, '''', '''''') + ''';
SET #in_report_name = ''' + REPLACE(#in_report_name, '''', '''''') + ''';
'
EXECUTE sp_RPT_DEBUG_LOG_ProzedurRun
'sp_RPT_Report_Translation'
,#ProzedurParameter
,#strSQL
,'' --#ProzedurDetail
;
--PRINT #strSQL
EXECUTE (#strSQL)
END
GO

pull SQL results for search criteria conditions

Notice the 2 queries below. The 1st one does a union on 4 queries. I'm trying to write #2 for search conditions based on the 3 SQL variables prefixed with an "#". So rather than doing a union, we have to take all 3 parameters into consideration for the search. And if any parameter/variable is '' (or NULL), just ignore that condition, but still perform the search. But all fields have to combine with each other for a single row/record in the search results.
How do I re-write QUERY #2 so that it pulls results based on the search conditions (#companyName, #primaryPhone and #postalCode)? I think each section in the where clause has to have some OR condition (so it doesn't skip the row for a ''/NULL search condition), but I'm curious how this is typically done. The #primaryPhone part of the where clause is a little trickier because it looks at both phone and fax.
QUERY #1
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
-- Company Name internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
client.name IS NOT NULL
AND client.name != ''
AND #companyName != ''
AND #companyName IS NOT NULL
AND client.name LIKE '%' + #companyName + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
-- Primary Phone/Fax internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + #primaryPhone + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
QUERY #2 (SEARCH)
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
(
client.name IS NOT NULL
AND client.name != ''
AND #companyName != ''
AND #companyName IS NOT NULL
AND client.name LIKE '%' + #companyName + '%'
)
AND
(
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + #primaryPhone + '%'
)
)
AND
(
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
EDIT New Rules
| Field = '' or NULL | Field != '' or NULL
---------------------+----------------------+-----------------------
Param = '' or NULL | Include Record | Include Record
---------------------+----------------------+-----------------------
Param != '' or NULL | Exclude Record | Include if Match
WHERE
(
#companyName = ''
OR #companyName IS NULL
OR client.name LIKE '%' + #companyName + '%'
)
AND
(
(
#primaryPhone = ''
OR #primaryPhone IS NULL
OR contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
#primaryPhone = ''
OR #primaryPhone IS NULL
OR contact.fax LIKE '%' + #primaryPhone + '%'
)
)
AND
(
#postalCode = ''
OR #postalCode IS NULL
OR address.postalcode LIKE #postalCode + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
could be written as
AND address.postalcode LIKE IsNull(#postalCode, '') + '%'
no need for testing that you have a variable at all, sql will ignore it in the execution when = '%'
a mass of ORs in my experience will really slow down the query (but look at the exe plan anyway). this is a heck of a lot easier on the eye also imo.

Using IF in SQL Function with 2 Table

I have a page like this
Baş Tar. --> Start Date
Bit. Tar --> End Date
I have a SQL like this for this page,
SELECT B.HESAP_NO, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2 AS 'TEKLIF',B.MUS_K_ISIM,
dbo.fngcodeme(B.HESAP_NO, B.DOVIZ_KOD, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2,'01/01/2011', '11/03/2011') AS 'YATAN',
(CASE WHEN B.DOVIZ_KOD = 21 THEN 'EUR' WHEN B.DOVIZ_KOD = 2 THEN 'USD' WHEN B.DOVIZ_KOD = 1 THEN 'TL' END) AS 'KUR',
D.AVUKAT,
(CASE WHEN D.HESAP IN (SELECT T_HESAP_NO FROM TAKIP) THEN
(SELECT CONVERT(VARCHAR(10),ICRA_TAR,103) FROM TAKIP WHERE T_HESAP_NO = D.HESAP)
ELSE ' ' END) AS 'ICRA TARİHİ',
(CASE WHEN D.HESAP IN (SELECT T_HESAP_NO FROM TAKIP) THEN
(SELECT CONVERT(VARCHAR(10),HACIZ_TAR,103) FROM TAKIP WHERE T_HESAP_NO = D.HESAP)
ELSE '' END) AS 'HACİZ TARİHİ'
FROM YAZ..MARDATA.S_TEKLIF B, AVUKAT D
WHERE B.HESAP_NO = D.HESAP
AND B.KAPANIS_TAR IS NULL
AND ISNULL(dbo.fngcodeme(B.HESAP_NO, B.DOVIZ_KOD, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2,'01/01/2011', '11/03/2011'),0) > 0
GROUP BY B.HESAP_NO, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2,B.DOVIZ_KOD ,B.MUS_K_ISIM, D.AVUKAT, D.HESAP
And this is my dbo.fngcodeme Function,
ALTER FUNCTION [dbo].[fngcodeme]
(
#HESAP INT, #DOV INT, #TEKLIF VARCHAR(10), #BAS VARCHAR(10), #BIT VARCHAR(10)
)
RETURNS FLOAT
AS
BEGIN
DECLARE #Result FLOAT
SET #Result = (SELECT SUM(TUTAR)
FROM YAZ..MARDATA.M_GHAREKET
WHERE TEMEL_HESAP = #HESAP
AND DOVIZ_KOD = #DOV
AND REF_KOD = 'GC'
AND BACAK_GRUP = 'PERT'
AND ISL_KOD = 1
AND ACIKLAMA LIKE '%' + #TEKLIF + '%'
AND ISL_TAR >= CONVERT(DATETIME, + '' + #BAS + '',103)
AND ISL_TAR <= CONVERT(DATETIME, + '' + #BIT + '',103)
)
RETURN #Result
END
What i want is
IF `Bit. Tar. (End Date)` is less or equal then 28/02/2011 --> Use M_HAREKET(table)
IF Baş. Tar. (Start Date) is great or equal then 01/03/2011 --> Use M_GHAREKET(table)
How can i do that?
Should i change SQL or Function? Which one?
If #BAS and #BIT are dates, pass them in as dates. Don't use VARCHAR.
ALTER FUNCTION [dbo].[fngcodeme]
(
#HESAP INT, #DOV INT, #TEKLIF VARCHAR(10), #BAS datetime, #BIT datetime
)
RETURNS FLOAT
AS
BEGIN
DECLARE #Result FLOAT
IF CONVERT(DATETIME, #BIT,103) <= '20110228'
SET #Result = (SELECT SUM(TUTAR)
FROM YAZ..MARDATA.M_HAREKET
WHERE TEMEL_HESAP = #HESAP
AND DOVIZ_KOD = #DOV
AND REF_KOD = 'GC'
AND BACAK_GRUP = 'PERT'
AND ISL_KOD = 1
AND ACIKLAMA LIKE '%' + #TEKLIF + '%'
AND ISL_TAR >= CONVERT(DATETIME, #BAS,103)
AND ISL_TAR <= CONVERT(DATETIME, #BIT,103)
)
ELSE
SET #Result = (SELECT SUM(TUTAR)
FROM YAZ..MARDATA.M_GHAREKET
WHERE TEMEL_HESAP = #HESAP
AND DOVIZ_KOD = #DOV
AND REF_KOD = 'GC'
AND BACAK_GRUP = 'PERT'
AND ISL_KOD = 1
AND ACIKLAMA LIKE '%' + #TEKLIF + '%'
AND ISL_TAR >= CONVERT(DATETIME, #BAS,103)
AND ISL_TAR <= CONVERT(DATETIME, #BIT,103)
)
RETURN #Result
END
As for the calling function, don't use region specific date formats. Stick to YYYYMMDD or one of the ISO/XML ones. So your query would be
SELECT B.HESAP_NO, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2 AS 'TEKLIF',B.MUS_K_ISIM,
dbo.fngcodeme(B.HESAP_NO, B.DOVIZ_KOD, B.TEKLIF_NO1 + '/' + B.TEKLIF_NO2,'20110101', '20110311') AS 'YATAN',
......