How to self join and case when - mysql

I have this monster query from a java application that I am reverse engineering.
`
SELECT
T.transferNumber,
T.TransferNumber,
T.BarrelsRequested - T.TotalBarrels br,
TrTy.TransferTypeName,
TrTa.SourceDest,
Ta.TankName,
SBP.SBPName,
T.Notes
FROM
RC.Transfers T,
RC.TransferTypes TrTy,
RC.TransferTank TrTa,
RC.Tanks Ta,
RC.ShipBargePipe SBP
WHERE
T.TransferTypeNumber = TrTy.TransferTypeNumber
AND T.TransferNumber = TrTa.TransferNumber
AND TrTa.TankNumber = Ta.TankNumber
AND T.SBPNumber = SBP.SBPNumber
AND T.StartStamp IS NOT NULL
AND T.EndStamp IS NULL
AND T.Void IS NULL
AND TrTy.TransferTypeName <> 'Truck'
UNION SELECT
T.transferNumber,
T.TransferNumber,
T.BarrelsRequested - T.TotalBarrels,
TrTy.TransferTypeName,
TrTa.SourceDest,
Ta.TankName,
'',
T.Notes
FROM
RC.Transfers T,
RC.TransferTypes TrTy,
RC.TransferTank TrTa,
RC.Tanks Ta
WHERE
T.TransferTypeNumber = TrTy.TransferTypeNumber
AND T.TransferNumber = TrTa.TransferNumber
AND TrTa.TankNumber = Ta.TankNumber
AND T.SBPNumber IS NULL
AND T.StartStamp IS NOT NULL
AND T.EndStamp IS NULL
AND T.Void IS NULL
AND TrTy.TransferTypeName <> 'Truck'
`
This returns a result set of:
But I really want:
Any help would be much appreciated. As mentioned in the picture, I want rows that have the same transfer number to show up on one line. I think I can achieve this using a self join, and
case when SourceDest = 's' AS 'FROM'
case when SourceDest = 'd' AS 'TO'
Also notice that when the type is Ship or Pipe, Then the from or To column becomes the SBPName depending on whether it is source or destination.
Thanks! Feel free to modify my question as you see fit too.
Edit*
Here is the java source code showing how they are grouping the rows together.
`
void updateRunning(Connection conn)
throws SQLException
{
Query q = new Query(conn);
this.jLabelRunningUpdate.setText("Reading");
this.jLabelRunningUpdate.setVisible(true);
q
.setQuery("SELECT T.transferNumber, T.TransferNumber, T.BarrelsRequested - T.TotalBarrels br, TrTy.TransferTypeName, TrTa.SourceDest, Ta.TankName, SBP.SBPName, T.Notes FROM RC.Transfers T, RC.TransferTypes TrTy, RC.TransferTank TrTa, RC.Tanks Ta, RC.ShipBargePipe SBP WHERE T.TransferTypeNumber = TrTy.TransferTypeNumber AND T.TransferNumber = TrTa.TransferNumber AND TrTa.TankNumber = Ta.TankNumber AND T.SBPNumber = SBP.SBPNumber AND T.StartStamp is not NULL AND T.EndStamp is NULL AND T.Void is NULL AND TrTy.TransferTypeName <> 'Truck' UNION SELECT T.transferNumber, T.TransferNumber, T.BarrelsRequested - T.TotalBarrels, TrTy.TransferTypeName, TrTa.SourceDest, Ta.TankName, '', T.Notes FROM RC.Transfers T, RC.TransferTypes TrTy, RC.TransferTank TrTa, RC.Tanks Ta WHERE T.TransferTypeNumber = TrTy.TransferTypeNumber AND T.TransferNumber = TrTa.TransferNumber AND TrTa.TankNumber = Ta.TankNumber AND T.SBPNumber is NULL AND T.StartStamp is not NULL AND T.EndStamp is NULL AND T.Void is NULL AND TrTy.TransferTypeName <> 'Truck'");
ResultSetCA transfers = q.execute(false);
this.jLabelRunningUpdate.setText("Updating");
String sourceTankList = "";
String destinationTankList = "";
ResultSetCA runningList = new ResultSetCA();
for (int count = 0; count < transfers.size(); count++)
{
sourceTankList = "";
destinationTankList = "";
String currentTNumber = transfers.getString(count, "transferNumber");
while ((count < transfers.size()) && (
currentTNumber.equals(transfers.getString(count, "transferNumber"))))
{
String sourceDest = transfers.getString(count, "sourceDest");
String tankName = transfers.getString(count, "tankName");
if (sourceDest.equals("s")) {
sourceTankList = sourceTankList + tankName + ", ";
} else {
destinationTankList = destinationTankList + tankName + ", ";
}
count++;
}
if (!sourceTankList.equals("")) {
sourceTankList = sourceTankList.substring(0, sourceTankList.length() - 2);
}
if (!destinationTankList.equals("")) {
destinationTankList =
destinationTankList.substring(0, destinationTankList.length() - 2);
}
count--;int lastCount = count;
String transferTypeName = transfers.getString(lastCount, "transferTypeName");
if (!transferTypeName.equals("Tank"))
{
String sbpName = transfers.getString(lastCount, "sbpName");
if (sourceTankList.equals("")) {
sourceTankList = sbpName;
} else {
destinationTankList = sbpName;
}
}
Number barrelsRemaining = transfers.getNumber(lastCount, "br");
Object BBLS;
Object BBLS;
if (barrelsRemaining == null) {
BBLS = "????";
} else {
BBLS = new Integer(barrelsRemaining.intValue());
}
Vector register = new Vector();
Integer transferNumber = transfers.getInteger(lastCount, "transferNumber");
String transferTName = transfers.getString(lastCount, "transferTypeName");
String notes = transfers.getString(lastCount, "notes");
register.add(transferNumber);
register.add(transferNumber);
register.add(BBLS);
register.add(transferTName);
register.add(sourceTankList);
register.add(destinationTankList);
register.add(notes);
runningList.add(register);
}
Object key = null;
if (this.jTableTransfersRunning.getSelectedRow() != -1) {
key = this.jTableTransfersRunning.getSelectedKey();
}
this.jTableTransfersRunning.fill(runningList);
if (runningList.size() > 0) {
if (key != null) {
this.jTableTransfersRunning.setSelectedKey(key);
}
}
this.jLabelRunningUpdate.setVisible(false);
}
`

EDITED
Give this a try:
SELECT
T.transferNumber,
T.BarrelsRequested - T.TotalBarrels AS `BBLs left`,
TrTy.TransferTypeName AS `Type`,
IF(TrTy.TransferTypeName = 'Tank',Ta.TankName,IFNULL(Ta.TankName,SBP.SBPName)) AS `From`,
IF(TrTy.TransferTypeName = 'Tank',Ta1.TankName,IFNULL(Ta1.TankName,SBP.SBPName)) AS `To`,
T.notes
FROM transfers T
JOIN transfertypes TrTy
ON T.TransferTypeNumber = TrTy.TransferTypeNumber
LEFT JOIN transfertank TrTa
ON T.TransferNumber = TrTa.TransferNumber
AND TrTa.SourceDest = 's'
LEFT JOIN tanks Ta
ON TrTa.TankNumber = Ta.TankNumber
LEFT JOIN transfertank TrTa1
ON T.TransferNumber = TrTa1.TransferNumber
AND TrTa1.SourceDest = 'd'
LEFT JOIN tanks Ta1
ON TrTa1.TankNumber = Ta1.TankNumber
LEFT JOIN shipbargepipe SBP
ON T.SBPNumber = SBP.SBPNumber
WHERE T.StartStamp IS NOT NULL
AND T.EndStamp IS NULL
AND T.Void IS NULL
AND TrTy.TransferTypeName <> 'Truck'
ORDER BY TRANSFERNUMBER

Join with this subquery instead of joining with TransferTank directly:
(SELECT t1.TransferNumber, t1.TankNumber, t1.SBPName AS From, t2.SBPName AS To
FROM TransferTank AS t1
JOIN TransferTank AS t2
ON t1.TransferNumber = t2.TransferNumber
AND t1.TankNumber = t2.TankNumber
WHERE t1.SourceDest = 's'
AND t2.SourceDesc = 'd') AS TrTa

Related

sum function based on unique date

actually i want a total value based on unique date
SELECT t2.stateName,
t3.`districtName`,t1.fingerDate,COUNT(a.arg1),COUNT(a.arg2),COUNT(a.arg3),COUNT(a.arg4),COUNT(a.arg5),COUNT(a.arg6),COUNT(a.arg7), COUNT(a.arg8),(COUNT(a.arg1) + COUNT(a.arg2) + COUNT(a.arg3) + COUNT(a.arg4) + COUNT(a.arg5) + COUNT(a.arg6) + COUNT(a.arg7))AtotalScreeningArg
FROM tbl_user AS t1
LEFT JOIN tbl_state AS t2 ON t1.addressState = t2.stateId
LEFT JOIN `tbl_district` AS t3 ON t1.addressDistrict = t3.`districtId`
LEFT JOIN (SELECT userId,
CASE WHEN occupation = "Truckers" OR occupation = "Drivers"
THEN occupation END arg1,
CASE WHEN (occupation = "Migrant")
THEN occupation END arg2,
CASE WHEN (hrg IS NULL OR hrg = " ") AND (`arg` IS NULL OR `arg` = " ")
THEN "Student" END arg3,
CASE WHEN (occupation = "Daily Wage")
THEN occupation END arg4,
CASE WHEN (occupation = "Salaried" OR occupation = "self Employed" OR occupation ="Unemployed" OR occupation = "Other")
THEN occupation END arg5,
CASE WHEN (ARG = "Female Partner (FPHRG)" OR ARG = "Partner / Spouse of FSW")
THEN ARG END arg6,CASE WHEN ARG = "Female Partner (FPARG)" THEN ARG END arg7,
CASE WHEN ARG = "TG (F-M)" THEN ARG END arg8,CASE WHEN hrg = "MSM" THEN hrg END arg9,
CASE WHEN hrg = "TG(M_F)" THEN hrg END arg10,CASE WHEN hrg = "FSW" THEN hrg END arg11,CASE WHEN hrg = "IDU" THEN hrg END arg12 FROM `tbl_user`
WHERE fingerDate IS NOT NULL OR fingerDate != " ")a ON t1.userId = a.userId
WHERE `t1`.`deleted` = "N" AND t1.userType = "user" AND `t1`.`fingerDate` >= '2018-11-01' AND `t1`.`fingerDate` <= '2018-12-01' AND t1.addressState = '34' AND t1.addressDistrict = '614' GROUP BY t1.userId
it gives result but not for unique date

Linq to SQL generates much slower query

I've got a SQL query that when I run it in SQL Server Mgmt Studio takes 15 seconds to complete. When I translate it to linq and run it in LINQPad it takes 1:50 to complete. Have I just completely bungled the "translation" to linq?
This is the SQL:
WITH details AS (
SELECT DISTINCT SerialNumber, OrgLevel3, OrgLevel4, [Status Label]
FROM vw_PSM_AssetIntransit
WHERE yyyyww = DATENAME(yy, GETDATE()) + RIGHT('00' + DATENAME(wk, GETDATE()), 2) AND pro_status <> 'retired'
)
SELECT OrgLevel3, OrgLevel4, COUNT(DISTINCT SerialNumber) Total,
SUM(CASE WHEN [Status Label] NOT IN ('15-21 Days InTransit', '8-14 Days InTransit', 'over 21 Days InTransit') THEN 1 ELSE 0 END) Compliant
FROM details
GROUP BY OrgLevel3, OrgLevel4
ORDER BY 1, 2
and this is the LINQ I translated it to:
var now = DateTime.Now;
var dtf = System.Globalization.DateTimeFormatInfo.CurrentInfo;
var calendar = dtf.Calendar;
var yearWW = now.Year * 100 + calendar.GetWeekOfYear(now, dtf.CalendarWeekRule, dtf.FirstDayOfWeek);
var badStatusLabels = new string[] { "15-21 Days InTransit", "8-14 Days InTransit", "over 21 Days InTransit" };
var details = (
from r in Vw_PSM_AssetIntransit
where r.yyyyww == yearWW && r.Pro_status != "retired"
select new { r.SerialNumber, r.OrgLevel3, r.OrgLevel4, r.StatusLabel }
).Distinct();
var data = from r in details
group r by new { r.OrgLevel3, r.OrgLevel4 } into grp
orderby grp.Key.OrgLevel3, grp.Key.OrgLevel4
select new
{
OrgLevel3 = grp.Key.OrgLevel3,
OrgLevel4 = grp.Key.OrgLevel4,
Total = grp.Select(x => x.SerialNumber).Distinct().Count(),
Compliant = grp.Sum(x => !badStatusLabels.Contains(x.StatusLabel) ? 1 : 0)
};
Console.WriteLine(data);
This is what LINQPad shows the SQL query came out as:
-- Region Parameters
DECLARE #p0 Int = 201816
DECLARE #p1 NVarChar(1000) = 'retired'
DECLARE #p2 NVarChar(1000) = '15-21 Days InTransit'
DECLARE #p3 NVarChar(1000) = '8-14 Days InTransit'
DECLARE #p4 NVarChar(1000) = 'over 21 Days InTransit'
DECLARE #p5 Int = 1
DECLARE #p6 Int = 0
-- EndRegion
SELECT [t3].[OrgLevel3], [t3].[OrgLevel4], (
SELECT COUNT(*)
FROM (
SELECT DISTINCT [t5].[SerialNumber]
FROM (
SELECT DISTINCT [t4].[SerialNumber], [t4].[OrgLevel3], [t4].[OrgLevel4], [t4].[Status Label]
FROM [vw_PSM_AssetIntransit] AS [t4]
WHERE ([t4].[yyyyww] = #p0) AND ([t4].[pro_status] <> #p1)
) AS [t5]
WHERE ((([t3].[OrgLevel3] IS NULL) AND ([t5].[OrgLevel3] IS NULL)) OR (([t3].[OrgLevel3] IS NOT NULL) AND ([t5].[OrgLevel3] IS NOT NULL) AND ((([t3].[OrgLevel3] IS NULL) AND ([t5].[OrgLevel3] IS NULL)) OR (([t3].[OrgLevel3] IS NOT NULL) AND ([t5].[OrgLevel3] IS NOT NULL) AND ([t3].[OrgLevel3] = [t5].[OrgLevel3]))))) AND ((([t3].[OrgLevel4] IS NULL) AND ([t5].[OrgLevel4] IS NULL)) OR (([t3].[OrgLevel4] IS NOT NULL) AND ([t5].[OrgLevel4] IS NOT NULL) AND ((([t3].[OrgLevel4] IS NULL) AND ([t5].[OrgLevel4] IS NULL)) OR (([t3].[OrgLevel4] IS NOT NULL) AND ([t5].[OrgLevel4] IS NOT NULL) AND ([t3].[OrgLevel4] = [t5].[OrgLevel4])))))
) AS [t6]
) AS [Total], [t3].[value] AS [Compliant]
FROM (
SELECT SUM([t2].[value]) AS [value], [t2].[OrgLevel3], [t2].[OrgLevel4]
FROM (
SELECT
(CASE
WHEN NOT ([t1].[Status Label] IN (#p2, #p3, #p4)) THEN #p5
ELSE #p6
END) AS [value], [t1].[OrgLevel3], [t1].[OrgLevel4]
FROM (
SELECT DISTINCT [t0].[SerialNumber], [t0].[OrgLevel3], [t0].[OrgLevel4], [t0].[Status Label]
FROM [vw_PSM_AssetIntransit] AS [t0]
WHERE ([t0].[yyyyww] = #p0) AND ([t0].[pro_status] <> #p1)
) AS [t1]
) AS [t2]
GROUP BY [t2].[OrgLevel3], [t2].[OrgLevel4]
) AS [t3]
ORDER BY [t3].[OrgLevel3], [t3].[OrgLevel4]

Why the query is giving result while the destCurrency is not 0 -

SELECT *
FROM xyz
WHERE applyat = 'anita'
AND applyAt = 'Create'
AND country = '50'
AND dest_country = '108'
AND originCurrency = 'EUR'
AND destCurrency = 0 AND isEnable = 'Y'
AND agentID = 0
AND Module = 'abc'
ORDER BY ruleID DESC
You should add quotes as it is a varchar
SELECT * FROM xyz WHERE applyat = 'anita' AND applyAt = 'Create' AND country = '50' AND dest_country = '108' AND originCurrency = 'EUR' AND destCurrency = '0' AND isEnable = 'Y' And agentID = 0 AND Module = 'abc' ORDER BY ruleID DESC

SQL CONCAT Function

I would like to create a Concate like:
CONCAT(OEEL.orderno+'-'+OEEL.ordersuf+'-'+OEEL.prodcat) AS "Unique"
SELECT OEEL.invoicedt, UCASE(OEEL.whse) AS Whse, OEEL.orderno, OEEL.ordersuf, OEEL.custno, UCASE(OEEL.shipto) AS Shipto, UCASE(OEEL.slsrepin) AS Slsrepin,
UCASE(OEEL.slsrepout) AS Slsrepout, OEEL.returnfl, OEEL.netamt, OEEL.wodiscamt, OEEL.discamtoth, OEEL.qtyship, OEEL.commcost, ICSS.csunperstk,
UCASE(ICSD.name) AS Name, UCASE(ICSD.region) AS Region, UCASE(OEEL.prodcat) AS Prodcat, UCASE(SASTA.descrip) AS Descrip, UCASE(OEEL.transtype)
AS Transtype, UCASE(ARSS.user2) AS User2, OEEL.transdt, ICSS.transdt AS "ICSS.Transdt", ICSD.transdt AS "ICSD.Transdt", SASTA.transdt AS "SASTA.Transdt",
ARSS.transdt AS "ARSS.Transdt", { fn CURDATE() } AS CURDATE1, { fn CURTIME() } AS CURTIME2,
CASE WHEN OEEL.returnfl = '0' THEN (OEEL.netamt - OEEL.wodiscamt - OEEL.discamtoth) ELSE (- 1 * (OEEL.netamt - OEEL.wodiscamt - OEEL.discamtoth))
END AS "SALES", CASE WHEN OEEL.returnfl = '0' THEN (OEEL.qtyship * OEEL.commcost * NVL(ICSS.csunperstk, 1))
ELSE (- 1 * OEEL.qtyship * OEEL.commcost * NVL(ICSS.csunperstk, 1)) END AS "COST",
(CASE WHEN OEEL.returnfl = '0' THEN (OEEL.netamt - OEEL.wodiscamt - OEEL.discamtoth) ELSE (- 1 * (OEEL.netamt - OEEL.wodiscamt - OEEL.discamtoth)) END)
- (CASE WHEN OEEL.returnfl = '0' THEN (OEEL.qtyship * OEEL.commcost * NVL(ICSS.csunperstk, 1))
ELSE (- 1 * OEEL.qtyship * OEEL.commcost * NVL(ICSS.csunperstk, 1)) END) AS GP
FROM { oj { oj { oj { oj PUB.oeel OEEL LEFT OUTER JOIN
PUB.icss ICSS ON OEEL.cono = ICSS.cono AND OEEL.shipprod = ICSS.prod AND OEEL.icspecrecno = ICSS.icspecrecno } LEFT OUTER JOIN
PUB.icsd ICSD ON OEEL.cono = ICSD.cono AND OEEL.whse = ICSD.whse } LEFT OUTER JOIN
PUB.sasta SASTA ON OEEL.cono = SASTA.cono AND OEEL.prodcat = SASTA.codeval } LEFT OUTER JOIN
PUB.arss ARSS ON OEEL.cono = ARSS.cono AND OEEL.custno = ARSS.custno AND OEEL.shipto = ARSS.shipto }
WHERE (OEEL.cono = 1) AND (OEEL.invoicedt BETWEEN { d '2014-06-02' } AND { d '2014-06-03' }) AND (SASTA.codeiden IN ('C', 'c'))
ORDER BY OEEL.custno, OEEL.shipto, OEEL.prodcat
The function has + (which in MySQL is not a concatenation symbol) between the variables.
Try:-
CONCAT_WS('-', OEEL.orderno, OEEL.ordersuf, OEEL.prodcat) AS `Unique`
CONCAT_WS does a concatenation With Separator .the first parameter is the separator with the others concatenated together.

MySQL to MSSQL Query Translation

I am a novice when it comes to MSSQL and have been trying to convert the following MySQL query without any joy. I am connecting to a MySQL Database within Microsoft SQL Server Management Studio via ODBC. This works great and very simple queries work just fine. However the following query is a bit more complicated(and probably not as optimized as it could be), and I am not able to get it working.
First query below is the original MySQL Query, and the second query is my attempted MSSQL translation.
MySQL Query
SELECT timestamp, `First Name`, `Last Name`, `Email Address`, `Department`, `Case`, `Partner`, `Category`, `Tag Title`, `Question`, `Answer`,
MAX(CASE `Secondary Metric Question` WHEN 'Support' THEN `Secondary Metric Question` end) AS 'Metric 1 Title',
MAX(CASE `Secondary Metric Question` WHEN 'Support' THEN `Answer` end) AS 'Metric 1 Answer',
MAX(CASE `Secondary Metric Question` WHEN 'Completeness' THEN `Secondary Metric Question` end) AS 'Metric 2 Title',
MAX(CASE `Secondary Metric Question` WHEN 'Completeness' THEN `Answer` end) AS 'Metric 2 Answer',
MAX(CASE `Secondary Metric Question` WHEN 'Policy' THEN `Secondary Metric Question` end) AS 'Metric 3 Title',
MAX(CASE `Secondary Metric Question` WHEN 'Policy' THEN `Answer` end) AS 'Metric 3 Answer',
`Message`,
CASE `Reply Requested` WHEN 1 THEN "YES" ELSE "NO" END AS "Reply Requested",
`Response Session`
FROM (
SELECT T0.timestamp, T8.first_name AS 'First Name', T8.last_name AS 'Last Name', T8.email AS 'Email Address', T0.dept AS 'Department', T0.case AS 'Case', T0.partner AS 'Partner', T3.title AS 'Category', T2.title AS 'Question', T2.private_title AS 'Tag Title', T6.title AS 'Secondary Metric Question', T0.answer AS 'Answer', T4.key AS 'Message', T4.reply_requested AS 'Reply Requested', T0.response_session AS 'Response Session'
FROM responses AS T0
LEFT JOIN qrs_metrics AS T1
ON T0.qrs_metric_id = T1.qrs_metric_id
LEFT JOIN quick_responses AS T2
ON T1.qrs_id = T2.qrs_id
LEFT JOIN custom_categories AS T3
ON T2.category = T3.original_id AND T3.user_id = T2.user_id
LEFT JOIN rre_aggregates AS T4
ON T0.comment_id = T4.id
LEFT JOIN widget_responses AS T5
ON T0.widget = T5.id
LEFT JOIN secondary_metrics AS T6
ON T1.metric_id = T6.id
LEFT JOIN private_messages AS T7
ON T4.id = T7.comment_id AND T7.type = 3
LEFT JOIN users AS T8
ON T2.user_id = T8.user_id
WHERE T0.timestamp >= '2014-02-17 00:00:00'
AND T0.qrs_metric_id = T1.qrs_metric_id
) tmp_table
GROUP BY `Response Session`
MSSQL Translation Attempt
SELECT [timestamp], [First Name], [Last Name], [Email Address], [Department], [Case], [Partner], [Category], [Tag Title], [Question], [Answer],
MAX(CASE [Secondary Metric Question] WHEN 'Support' THEN [Secondary Metric Question] end) AS 'Metric 1 Title',
MAX(CASE [Secondary Metric Question] WHEN 'Support' THEN [Answer] end) AS 'Metric 1 Answer',
MAX(CASE [Secondary Metric Question] WHEN 'Completeness' THEN [Secondary Metric Question] end) AS 'Metric 2 Title',
MAX(CASE [Secondary Metric Question] WHEN 'Completeness' THEN [Answer] end) AS 'Metric 2 Answer',
MAX(CASE [Secondary Metric Question] WHEN 'Policy' THEN [Secondary Metric Question] end) AS 'Metric 3 Title',
MAX(CASE [Secondary Metric Question] WHEN 'Policy' THEN [Answer] end) AS 'Metric 3 Answer',
[Message],
CASE [Reply Requested] WHEN 1 THEN 'YES' ELSE 'NO' END AS 'Reply Requested',
[Response Session]
FROM (
SELECT T0.[timestamp], T8.first_name AS 'First Name', T8.last_name AS 'Last Name', T8.email AS 'Email Address', T0.dept AS 'Department', T0.[case] AS 'Case', T0.partner AS 'Partner', T3.title AS 'Category', T2.title AS 'Question', T2.private_title AS 'Tag Title', T6.title AS 'Secondary Metric Question', T0.answer AS 'Answer', T4.[key] AS 'Message', T4.reply_requested AS 'Reply Requested', T0.response_session AS 'Response Session'
FROM AZUREMYSQL...responses AS T0
LEFT JOIN AZUREMYSQL...qrs_metrics AS T1
ON T0.qrs_metric_id = T1.qrs_metric_id
LEFT JOIN AZUREMYSQL...quick_responses AS T2
ON T1.qrs_id = T2.qrs_id
LEFT JOIN AZUREMYSQL...custom_categories AS T3
ON T2.category = T3.original_id AND T3.user_id = T2.user_id
LEFT JOIN AZUREMYSQL...rre_aggregates AS T4
ON T0.comment_id = T4.id
LEFT JOIN AZUREMYSQL...widget_responses AS T5
ON T0.widget = T5.id
LEFT JOIN AZUREMYSQL...secondary_metrics AS T6
ON T1.metric_id = T6.id
LEFT JOIN AZUREMYSQL...private_messages AS T7
ON T4.id = T7.comment_id AND T7.type = 3
LEFT JOIN AZUREMYSQL...users AS T8
ON T2.user_id = T8.user_id
WHERE T0.timestamp >= '2014-02-17 00:00:00'
AND T0.qrs_metric_id = T1.qrs_metric_id
) tmp_table
GROUP BY [Response Session]
The current error I am receiveing in SSMS is
Column 'tmp_table.timestamp' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If anyone can help out I would really appreciate it.
Thanks
You need to have all columns that are not aggregates in the GROUP BY.
Edit: Cant use DISTINCT here, perhaps with an nested select but GROUP BY will do just fine.
<pre>
<?php
class DB_mssql
{
function modifyQuery($query)
{
$query = str_replace("`", "", $query);
$query = str_replace( array('[',']') , '' , $query );
$tablesName = $this->getTableName($query);
$tableNamesWithoutAlise = $this->removeAliseName($tablesName);
$tableNamesWithPrefix = $this->prefixDBName($tableNamesWithoutAlise);
// Group By Function Call
$query = $this->getGroupBy($query);
// Order By Function Call
$query = $this->getOrderBy($query);
//replace Limit keyword with TOP keyword
$query = $this->getLimit($query);
// MSSQLDateFormat function call
$query = $this->getMSSQLDateFormat($query);
/*force index => WITH index*/
preg_match_all("#\sforce[\s]*index[\s]*\(\w*\)[\s]*#i",$query,$forceIndex);
if(!empty($forceIndex['0']['0']))
{
$forceString = $forceIndex['0']['0'].')';
$forceString = str_ireplace('force index','WITH (index',$forceString);
}
// Changed use index to with index
preg_match_all("#\suse[\s]*index[\s]*\(\w*\)[\s]*#i",$query,$useIndex);
if(!empty($useIndex['0']['0']))
{
$useString = $useIndex['0']['0'].')';
$useString = str_ireplace('use index','WITH (index',$useString);
}
/*Interval 10 date*/
preg_match_all("#INTERVAL\s[0-9]*\sday#i",$query,$intervalIndex);
if(!empty($intervalIndex[0][0]))
{
$intervalString = explode(" ",$intervalIndex[0][0]);
$intervalString = $intervalString[1];
} else {
$intervalString = '';
}
// Patterns
$patterns[0] ='#(?<![\w])secure_pgatxn.(?![\w][.])#i';
$patterns[1] ='#(?<![\w])secure_pga.(?![\w][.])#i';
$patterns[2] ='#\sIFNULL#i';
$patterns[3] = '#[\s]{1,}WHERE[\s]{1,}1#i';// where 1 should be replaced with WHERE 1=1
$patterns[4] ='#\sforce index[\s]*\(\w*\)[\s]*#i';// Force Index is replaced with With Index
$patterns[5] ='#\suse\sindex[\s]*\(\w*\)[\s]*#i';// use Index is replaced with with index
$patterns[6] ='#[\s]*&&{1}[\s]*#i';
$patterns[7] = '#IF[\s]*\([\s]*#i';// IF should be replaced with where IIF
$patterns[8] = '#now\([\s]*#i';// Now() function should be replaced with getutcdate()
$patterns[10] = '#[\W]DATE[\s]*\([\s]*#i';// Mysql Date() is changed to CONVERT (date,GETDATE())
$patterns[11] = '#DATE_FORMAT[\s]*\([\s]*#i';// date_format() function should be replaced with format
$patterns[12] = '#[\s]*(%Y{1}-%m{1}-%d{1})#i';// Change '%Y-%m-%d' patteren to 'yyyy-MM-dd'
$patterns[13] = '#%m{1} %d{1}#i';// Change '%m %d' patteren to 'MM dd' \'
$patterns[14] = '#DATE_SUB\([\s]*#i';// DATE_SUB() function accepts 3 parameters// curdate
$patterns[15] = '#CURDATE\([\s]*#i';// DATE_SUB() function accepts 3 parameters// curdate
$patterns[16] ='#\,[\s]*INTERVAL\s[0-9]*\sDAY#i';// INTERVAL 1 DAY is replaced with ''
$patterns[17] ='#[\s]*DATE_ADD\([\s]*#i';// Mysql Date() is changed to CONVERT (date,GETDATE())
$patterns[18] ='#[\s]*\|\|[\s]*#i'; // || to OR
$patterns[19] ='#(?<![\w])secure_lib.(?![\w][.])#i';
$patterns[20] = '#UCASE\([\s]*#i';
// Replacement Queries
$replacements[0] = ' ';
$replacements[1] = ' ';
$replacements[2] = ' ISNULL';
$replacements[3] = ' WHERE 1=1 ';
$replacements[4] = isset($forceString)?$forceString:''.' ';
$replacements[5] = isset($useString)?$useString:''.' ';
$replacements[6] = ' AND ';
$replacements[7] = 'IIF(';
$replacements[8] = 'GETDATE(';
$replacements[10] = ' CONVERT(date,';
$replacements[11] = 'FORMAT(';
$replacements[12] = 'yyyy-MM-dd';
$replacements[13] = 'MM dd';
$replacements[14] = ' DATEADD(DAY,-'.$intervalString.',';
$replacements[15] = 'GETDATE(';
$replacements[16] = '';
$replacements[17] = ' DATEADD(DAY,'.$intervalString.',';
$replacements[18] = ' OR ';
$replacements[19] = ' ';
$replacements[20] = 'UPPER(';
$query = preg_replace($patterns, $replacements, $query);
$query = $this->strReplaceTableName($query, $tableNamesWithPrefix);
return $query;
}
// Function To Change Limit to Top
function getLimit($query)
{
preg_match_all("#LIMIT[^\w]{1,}([0-9]{1,})[\s]*([\,]{0,})[\s]*([0-9]{0,})#i",$query,$matches);
$patterns = '#LIMIT[^\w]{1,}([0-9]{1,})[\s]*([\,]{0,})[\s]*([0-9]{0,})#i';
$replacements = '';
$query = preg_replace($patterns, $replacements, $query);
if(!empty($matches[1][0]) && empty($matches[3][0]))
{
$query = str_ireplace("SELECT ", "SELECT TOP ".$matches[1][0]." ", $query);
}
else if(!empty($matches[3][0]))
{
$limitQuery = " OFFSET ".$matches[1][0]." ROWS FETCH NEXT ".$matches[3][0]." ROWS ONLY";
if(stripos($query, "ORDER BY"))
{
$query .= $limitQuery;
}
else
{
$selectList = $this->selectList($query,"SELECT","FROM");
$selectList = $this->sqlParser($selectList);
$selectList = preg_replace('#[\s]as[\s]\w*#i', " ", $selectList);
$query .= " ORDER BY ".$selectList[0].$limitQuery;
}
}
return $query;
}
// Function To Change DateFormat
function getMSSQLDateFormat($query)
{
if(stripos($query, "%b %d"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'%b{1}[\s]*%d{1}\'[\s]*\)#iU",$query,$dateFormat);
if(!empty($dateFormat))
{
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"convert(char(3), ".$columnName.", 0)+' '+CONVERT(char(2), ".$columnName.", 4)",$query);
}
return $query;
}
else if(strpos($query, "%Y-%M"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'%Y{1}[\s]*-%M{1}\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"DATENAME(year,".$columnName.")+'-'+DATENAME(month,".$columnName.")",$query);
return $query;
}
else if(stripos($query, "%Y-%m"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'%Y{1}[\s]*-%m{1}\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"CONVERT(VARCHAR(7), ".$columnName.", 120)",$query);
return $query;
}
else if(stripos($query, "%M %d, %Y") || stripos($query, "%M %d. %Y"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'%M{1} %d{1}[\,|\.][\s]*%Y{1}\'[\s]*\)#iU",$query,$dateFormat);
foreach($dateFormat[0] as $key => $value)
{
$columnName = explode(",",$dateFormat[0][$key]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][$key],"CONVERT(VARCHAR(12), ".$columnName.", 107)",$query);
}
return $query;
}
else if(stripos($query, "%d/%m/%Y %H:%i:%S"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'\%d/\%m/\%Y[\s]*\%H:\%i:\%S\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"CONVERT(VARCHAR(10), ".$columnName.", 103)+' '+CONVERT(VARCHAR(18),".$columnName.",108)",$query);
return $query;
}
else if(stripos($query, "%d%m%Y"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w]*.*\)#i",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0]," REPLACE(CONVERT(VARCHAR(10),".$columnName.",103), '/','')",$query);
return $query;
}
else if(stripos($query, "%d/%m/%Y"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'\%d{1}/\%m{1}/\%Y{1}\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"CONVERT(VARCHAR(10), ".$columnName.", 103)",$query);
return $query;
}
else if(stripos($query, "%d %M,%Y"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'\%d{1}[\s]*\%M{1}[,]\%Y{1}\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"CONVERT(VARCHAR(11), ".$columnName.", 106)",$query);
return $query;
}
else if(stripos($query, "%H:00"))
{
preg_match_all("#DATE_FORMAT[\s]*\([\s]*[\w].*[,]{1}[\s]*\'[\s]*\%H{1}:00[\s]*\'[\s]*\)#iU",$query,$dateFormat);
$columnName = explode(",",$dateFormat[0][0]);
$columnName = str_ireplace("date_format(","",$columnName[0]);
$query = str_ireplace($dateFormat[0][0],"RIGHT(100 + DATEPART(HOUR, ".$columnName."),2)+':00'",$query);
return $query;
}
else if(stripos($query, "datediff"))
{
preg_match_all("#datediff[\s]*\([\s]*[\w].*[,]{1}[\s]*[\w].*[\s]*\)#iU",$query,$dateDiff);
if (isset($dateDiff[0])) {
foreach($dateDiff[0] as $key => $value)
{
$columnName = explode(",",$dateDiff[0][$key]);
if (count($columnName) < 3) {
$Param1 = substr($columnName[1],0,-1);
$Param2 = str_ireplace("datediff("," ",$columnName[0]);
$query = str_ireplace($dateDiff[0][$key],"datediff(DAY,$Param1,$Param2)",$query);
}
}
}
return $query;
}
else
{
return $query;
}
}
// Function To Select List To Order BY Clause
function getOrderBy($query)
{
/*Order By functionality starts*/
preg_match_all("#order[\s]by[^\w]{1,}([0-9]{1,})([\,]{0,})([0-9]{0,})#i",$query,$orderByNum);
if(!empty($orderByNum[0]))
{
$selectList = $this->selectList($query,"SELECT","FROM");
$orderByList = $this->orderByList($query,"ORDER BY","DESC");
$selectList = $this->sqlParser($selectList);
$selectList = preg_replace('#[\s]as[\s]{1,}\w*#i', " ", $selectList);
$orderByArr = explode(",",$orderByList);
$orderByArr = array_map('trim',$orderByArr);
/**Code for gropup by 1*/
if(!empty($orderByNum[0]))
{
$orderByCol=array();
foreach($orderByArr as $colno)
{
$orderByCol[]=$selectList[$colno-1];
}
}
if(!empty($orderByNum[0]))
{
$orderBy = implode(",",$orderByCol);
}
if(stripos($query, "ORDER BY"))
{
$query = preg_replace('#order[\s]by[^\w]{1,}([0-9]{1,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})([\,]{0,})([0-9]{0,})#i', "ORDER BY $orderBy ", $query);
}
}
return $query;
/*Ends here*/
}
// Function To Select List To Group BY Clause
function getGroupBy($query)
{
preg_match_all("#group[\s]by\s#i",$query,$groupByWord);
preg_match_all("#group[\s]by[^\w]{1,}([0-9]{1,})([\,]{0,})([0-9]{0,})#i",$query,$groupByNum);
$groupBy = !empty($groupByWord[0])?$groupByWord[0]:$groupByNum[0];
if(!empty($groupBy))
{
$selectList = $this->selectList($query,"SELECT","FROM");
$groupByList = $this->groupByList($query);
$selectList = $this->sqlParser($selectList);
$selectList = preg_replace("#[\s]as[\s]{1,}\w*#i", " ", $selectList);
$selectList = $this->removeAggregateFunc($selectList);
$groupByArr = explode(",",$groupByList);
$groupByArr = array_map('trim',$groupByArr);
/**Code for gropup by 1*/
if(!empty($groupByNum[0]))
{
$groupByCol=array();
foreach($groupByArr as $colno)
{
$groupByCol[]=$selectList[$colno-1];
}
}
if(!empty($groupByNum[0]))
{
$combineVal = array_merge_recursive($groupByCol,$selectList);
$combineVal = array_map('trim',$combineVal);
$combineVal = array_unique($combineVal);
$groupBy = implode(",",$combineVal);
}
else
{
$combineVal = array_merge_recursive($groupByArr,$selectList);
$combineVal = array_map('trim',$combineVal);
$combineVal = array_unique($combineVal);
$groupBy = implode(",",$combineVal);
}
$trimmed_array=array_map('trim',$groupByArr);
if(stripos($query, "ORDER BY"))
{
$query = preg_replace('#GROUP BY[\s\S]+?ORDER BY#i', "GROUP BY $groupBy ORDER BY ", $query);
}
else
{
$query = preg_replace('#GROUP BY[\s]{1,}.*#i', "GROUP BY ".$groupBy, $query);
}
}
return $query;
}
// Function To Remove Aggregate Function From group by list
function removeAggregateFunc($selectList)
{
if(!empty($selectList))
{
foreach($selectList as $key => $val)
{
if(stripos($val, "sum(") !== false)
{
unset($selectList[$key]);
}
else if(stripos($val, "count(") !== false)
{
unset($selectList[$key]);
}
else if(stripos($val, "MAX(") !== false)
{
unset($selectList[$key]);
}
else if(stripos($val, "MIN(") !== false)
{
unset($selectList[$key]);
}
else if(stripos($val, "AVG(") !== false)
{
unset($selectList[$key]);
}
}
}
return $selectList;
}
function groupByList($string){
if(stripos($string, "ORDER BY"))
{
preg_match_all("#group\sby(?s)(.*)order\sby#i",$string,$groupByOrderby);
return $groupByOrderby[1][0];
}
else if(stripos($string, "limit"))
{
preg_match_all("#group\sby(?s)(.*)\slimit#i",$string,$groupByLimit);
return $groupByLimit[1][0];
}
else if(stripos($string, "having"))
{
preg_match_all("#group\sby(?s)(.*)\shaving#iU",$string,$groupByHaving);
return $groupByHaving[1][0];
}
else
{
preg_match_all("#group\sby(?s)(.*)#i",$string,$groupBy);
return $groupBy[1][0];
}
}
function orderByList($string, $start, $end){
$string = ' ' . $string;
$ini = stripos($string, $start);
if ($ini == 0) return '';
$ini += strlen($start);
if(stripos($string, "DESC") === false)
{
return substr($string, $ini);
}
else
{
$len = stripos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}
}
// Function Used to select column list from Mysql Query
function selectList($string, $start, $end){
preg_match_all("#select(?s)(.*)[\W]from#iU",$string,$selectFrom);
return $selectFrom[1][0];
}
// Function Used to select column list from Mysql Query
function sqlParser($str)
{
$str = str_split($str);
$tokens = array();
$token = "";
$stack = array();
foreach($str as $char) {
if($char == "," && empty($stack)) {
$tokens[] = trim($token);
$token = "";
} else {
$token = $token .$char;
if($char == '(') {
array_unshift($stack, $char);
}
if($char == ')') {
array_shift($stack);
}
}
}
$tokens[] = trim($token);
return $tokens;
}
// Function Used to get TableName from Mysql Query
function getTableName($query)
{
$tables = array();
$query_structure = explode( ' ', strtolower( preg_replace('!\s+!', ' ', $query) ) );
$searches_from = array_keys( $query_structure , 'from');
$searches_join = array_keys( $query_structure , 'join');
$searches_update = array_keys( $query_structure , 'update');
$searches_into = array_keys( $query_structure , 'into');
$searches = array_merge($searches_join , $searches_from , $searches_update , $searches_into);
foreach($searches as $search ){
if(isset($query_structure[$search+1])){
$tables[] = trim( $query_structure[$search+1] , '` ');
}
}
$patterns[1] ='#(?<![\w])secure_pgatxn.(?![\w][.])#i';
$patterns[2] ='#(?<![\w])secure_pga.(?![\w][.])#i';
$patterns[3] ='#(?<![\w])secure_lib.(?![\w][.])#i';
$replacements[1] = '';
$replacements[2] = '';
$replacements[3] = '';
$tables = preg_replace($patterns, $replacements,$tables);
return $tables;
}
// Function Used to Prefix Database Name. In MSSQL, we have to prefix DB Name
function prefixDBName($tableList)
{
$tableArray = array(
"job_queue_notification_log"=>"secure_pga.dbo.job_queue_notification_log"
,"old_pga_customer_card"=>"secure_pga.dbo.old_pga_customer_card"
);
$tableNamesWithPrefix = array();
foreach($tableList as $tableName) {
$tableNamesWithPrefix[$tableName] = $tableArray[$tableName];
}
return $tableNamesWithPrefix;
}
function getSubStr($query, $fromStr, $toStr) {
$fromStrLen = strlen($fromStr);
$startingPos = stripos($query, $fromStr) + $fromStrLen;
$endingPos = stripos($query, $toStr);
if(empty($endingPos))
{
return substr($query, $startingPos);
}
else{
return substr($query, $startingPos, ($endingPos - $startingPos));
}
}
function removeAliseName($tablesName) {
$cleanTablesName = array();
foreach($tablesName as $tableName) {
$temp = explode(" ",$tableName);
$cleanTablesName[] = trim($temp[0],"[]");
}
return $cleanTablesName;
}
function strReplaceTableName($query, $tableNames){
foreach($tableNames as $tableNameBare => $tableNameWithPrefix) {
if(strlen($tableNameBare)>3){
$patterns[]='#\b'.$tableNameBare.'\b#iU';
$replacements[]=$tableNameWithPrefix.'';
}
}
$query = preg_replace($patterns, $replacements, $query);
return $query;
}
// }}}
}
// Object Initializations
$DB_mssql = new DB_mssql();
//Mysql Query
$mysqlQuery = "SELECT id,name FROM table_name WHERE id = 16474 ORDER BY id DESC LIMIT 1,100";
//MSSQL Converted Query
$MssqlQuery = $DB_mssql->modifyQuery($mysqlQuery);
?>
</pre>