Getting 0 rows returned on query - sql

so let me start will the basic table layout for all tables involved:
#zip_code_time_zone
+----+----------+-----------+
| id | zip_code | time_zone |
+----+----------+-----------+
| 1 | 00544 | -1 |
| 2 | 00601 | -3 |
| 3 | 00602 | 0 |
| 4 | 00603 | -3 |
| 5 | 00604 | 0 |
+----+----------+-----------+
#pricing_record
+------+---------------+--------------------+
| id | location_code | service_center_zip |
+------+---------------+--------------------+
| 7119 | TX725 | 79714 |
| 7121 | TX734 | 75409 |
| 7122 | TX737 | 78019 |
| 7124 | TX742 | 75241 |
| 7126 | TX751 | 77494 |
+------+---------------+--------------------+
#transaction_record
+----+-----------------+------------------+--------------+--------------+
| id | truck_stop_code | create_date | gps_verified | central_time |
+----+-----------------+------------------+--------------+--------------+
| 1 | CA428 | 05/01/2015 14:52 | 0 | NULL |
| 2 | CA343 | 05/01/2015 19:10 | 0 | NULL |
| 3 | CA223 | 05/01/2015 09:28 | 0 | NULL |
| 4 | CA721 | 05/01/2015 07:55 | 0 | NULL |
| 5 | MN336 | 05/01/2015 06:46 | 0 | NULL |
+----+-----------------+------------------+--------------+--------------+
When I was working on this project an issue was noticed with the create_date column in transaction_record. It needs to be converted to central time, so I wrote an update query, but I have been unable to successfully set the central_time column. My query is below:
query
UPDATE t
SET t.central_time = DATEADD(hour, z.time_zone,CONVERT(DATETIME, t.create_date, 120))
FROM eagle_devel.dbo.zip_code_time_zone z
INNER JOIN eagle_devel.dbo.pricing_record p ON z.zip_code = p.service_center_zip
INNER JOIN eagle_devel.dbo.transaction_record t ON t.truck_stop_code = p.location_code
This is what i get when I run the query
(0 row(s) affected)
NOTES
The time_zone column in #zip_code_time_zone is not the standard UTC it is the difference to calculate to central
I am still working on this as we speak, just looking for some extra assistance to see if someone else can fix it faster than myself.

Try like this instead with little changes, table you are updating should be in FROM clause and then adjust the JOIN accordingly
UPDATE t
SET t.central_time = DATEADD(hour, z.time_zone,CONVERT(DATETIME, t.create_date, 120))
FROM eagle_devel.dbo.transaction_record t
INNER JOIN eagle_devel.dbo.pricing_record p ON t.truck_stop_code = p.location_code
INNER JOIN eagle_devel.dbo.zip_code_time_zone z ON z.zip_code = p.service_center_zip

Related

Output multiple rows after joining and pivoting multiple tables

I have a couple of tables (in a SQL Server 2014 SP2 database) on which I have successfully pivoted (thanks to lptr in Creating SQL pivot where duplicate column names exist). The next problem is that each datasource has one or more datapoints, but I am only getting one of the datapoints, per datasource.
The tables looks like this:
dataSourceSnapshot
| snapshotId | snapshotTime |
-----------------------------------
| 1 | 2021-12-01 07:00 |
| 2 | 2021-12-02 07:00 |
...
datasource
| snapshotId | dsRecordId | dsId | dsName | dsTableDate |
---------------------------------------------------------------
| 1 | 1 | 1 | cpu | 2021-12-01 07:00 |
| 1 | 2 | 2 | mem | 2021-12-01 07:00 |
| 1 | 3 | 3 | cache | 2021-12-01 07:00 |
| 2 | 4 | 1 | cpu | 2021-12-01 07:00 |
| 2 | 5 | 2 | mem | 2021-12-01 07:00 |
| 2 | 6 | 3 | cache | 2021-12-01 07:00 |
...
datasourceProperty
This is a truncated list of datasource properties.
| dsRecordId | dsPropPropertyRecordId | dsPropPropertyName | dsPropPropertyValue |
----------------------------------------------------------------------------------
| 1 | 1 | id | 1 |
| 1 | 2 | description | cpu stats |
| 1 | 3 | name | cpu |
| 1 | 4 | collectInterval | 300 |
| 1 | 5 | group | |
| 1 | 6 | dataPoints | System.Object[] |
| 2 | 7 | id | 2 |
| 2 | 8 | description | memory stats |
| 2 | 9 | name | mem |
| 2 | 10 | collectInterval | 300 |
| 2 | 11 | group | |
| 2 | 12 | dataPoints | System.Object[] |
| 3 | 13 | id | 3 |
| 3 | 14 | description | |
| 3 | 15 | name | cache |
| 3 | 16 | collectInterval | 600 |
| 3 | 17 | group | |
| 3 | 18 | dataPoints | System.Object[] |
...
datapointProperty
This is a truncated list of datapoint properties.
| dsRecordId | dpRecordId | dpPropertyName | dpPropertyValue |
-----------------------------------------------------------------
| 1 | 1 | id | 1 |
| 1 | 2 | datasourceId | 1 |
| 1 | 3 | name | cpuState |
| 1 | 4 | description | |
| 1 | 5 | alertExpr | != 0 0 |
| 1 | 6 | type | 2 |
| 1 | 7 | id | 2 |
| 1 | 8 | datasourceId | 1 |
| 1 | 9 | name | freePercent |
| 1 | 10 | description | CPU utilization |
| 1 | 11 | alertExpr | >= 90 90 |
| 1 | 12 | type | 2 |
| 2 | 13 | id | 3 |
| 2 | 14 | datasourceId | 2 |
| 2 | 15 | name | freePercent |
| 2 | 16 | description | Memory utilization |
| 2 | 17 | alertExpr | >= 90 90 |
| 2 | 18 | type | 2 |
| 3 | 19 | id | 4 |
| 3 | 20 | datasourceId | 3 |
| 3 | 21 | name | state |
| 3 | 22 | description | |
| 3 | 23 | alertExpr | = 1 1 1 |
| 3 | 24 | type | 4 |
...
I am trying to get a row per datasource (but only the most recent instance of that datasource's entry) and per datapoint, which includes all of the datasource properties. Something like this:
| dsRecordId | id | description | name | collectInterval | group | dataPoints | dp_id | dp_datasourceId | dp_name | dp_description | dp_alertExpr | dp_type |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | 1 | cpu stats | cpu | 300 | | System.Object[] | 1 | 1 | cpuState | | != 0 0 | 2 |
| 1 | 1 | cpu stats | cpu | 300 | | System.Object[] | 2 | 1 | freePercent | | >= 90 90 | 2 |
| 2 | 2 | memory stats | mem | 300 | | System.Object[] | 3 | 2 | freePercent | Memory utilization | >= 90 90 | 2 |
| 3 | 3 | | cache | 600 | | System.Object[] | 4 | 3 | state | | = 1 1 1 | 4 |
I have a bit of T-SQL that will pivot, but because datasources and datapoints both have id, name, and description properties, I have to exclude those properties in the pivot. This query:
DECLARE
#dsPropPropertyColumns NVARCHAR(MAX) = '',
#dpPropertyColumns NVARCHAR(MAX) = '',
#sql NVARCHAR(MAX) = '';
-- select the property names
--- properties in the datasourceProperty table
SELECT #dsPropPropertyColumns = (
SELECT DISTINCT '[' + [dsPropPropertyName] + ']' + ','
FROM dbo.dataSourceSnapshot dss
LEFT OUTER JOIN dbo.datasource ds ON ds.snapshotId = dss.snapshotId
LEFT OUTER JOIN dbo.datasourceProperty dsp ON dsp.dsRecordId = ds.dsRecordId
WHERE dss.snapshotTime = (
SELECT MAX(snapshotTime) FROM dbo.dataSourceSnapshot
)
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)')
--- properties in the datapointProperty table
SELECT #dpPropertyColumns = (
SELECT DISTINCT '[' + [dpPropertyName] + ']' + ','
FROM dbo.dataSourceSnapshot dss
LEFT OUTER JOIN dbo.datasource ds ON ds.snapshotId = dss.snapshotId
LEFT OUTER JOIN dbo.datapointProperty dp ON dp.dsRecordId = ds.dsRecordId
WHERE dss.snapshotTime = (
SELECT MAX(snapshotTime) FROM dbo.dataSourceSnapshot
)
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)')
-- remove the trailing comma
SET #dsPropPropertyColumns = LEFT(#dsPropPropertyColumns, LEN(#dsPropPropertyColumns) - 1);
SET #dpPropertyColumns = LEFT(#dpPropertyColumns, LEN(#dpPropertyColumns) - 1);
-- construct dynamic SQL
SET #sql ='
SELECT * FROM (
SELECT dsp.dsRecordId, dsp.dsPropPropertyName, dsp.dsPropPropertyValue, CONCAT(''dp_'', dp.dpPropertyName) as dpPropertyName, dp.dpPropertyValue
FROM dbo.snapshot dss
LEFT OUTER JOIN dbo.datasource ds ON ds.snapshotId = dss.snapshotId
LEFT OUTER JOIN dbo.datasourceProperty dsp ON dsp.dsRecordId = ds.dsRecordId
LEFT OUTER JOIN dbo.datapointProperty dp ON dp.dsRecordId = ds.dsRecordId
WHERE dss.snapshotTime = (
SELECT MAX(snapshotTime) FROM dbo.dataSourceSnapshot
)
) t1
PIVOT (
MAX(dsPropPropertyValue) FOR dsPropPropertyName IN ('+ #dsPropPropertyColumns +')
) AS pivot_table
PIVOT (
MAX(dpPropertyValue) FOR dpPropertyName IN ('+ #dpPropertyColumns +')
) AS pivot_table2
ORDER BY id
'
EXECUTE sp_executesql #sql;
Produces this output:
| dsRecordId | id | description | name | collectInterval | group | dataPoints | dp_id | dp_datasourceId | dp_name | dp_description | dp_alertExpr | dp_type |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | 1 | cpu stats | cpu | 300 | | System.Object[] | 1 | 1 | cpuState | CPU utilization | >= 90 90 | 2 |
| 2 | 2 | memory stats | mem | 300 | | System.Object[] | 3 | 2 | freePercent | Memory utilization | >= 90 90 | 2 |
| 3 | 3 | | cache | 600 | | System.Object[] | 4 | 3 | state | | = 1 1 1 | 4 |
This output shows one row for the "cpu" datasource (which has two datapoints). Confusingly, it also shows the datapoint (dp_) description and alertExpr values for the CPU's freePercent datapoint, with the "cpuState" dp_name.
In Creating SQL pivot where duplicate column names exist, it was suggested to use:
ROW_NUMBER() OVER(partition by dp.dsRecordId, dp.dpPropertyName order by dp.dpRecordId) as dpPropertyName
With this T-SQL:
SELECT dsp.dsRecordId, dsp.dsPropPropertyName, dsp.dsPropPropertyValue, ROW_NUMBER() OVER(partition by dp.dsRecordId, dp.dpPropertyName order by dp.dpRecordId) as dpPropertyName, dp.dpPropertyValue
FROM logicmonitor.dataSourceSnapshot dss
LEFT OUTER JOIN logicmonitor.datasource ds ON ds.dataSourceSnapshotId = dss.dataSourceSnapshotId
LEFT OUTER JOIN logicmonitor.datasourceProperty dsp ON dsp.dsRecordId = ds.dsRecordId
LEFT OUTER JOIN logicmonitor.datapointProperty dp ON dp.dsRecordId = ds.dsRecordId
WHERE dss.dataSourceSnapshotTime = (
SELECT MAX(dataSourceSnapshotTime) FROM logicmonitor.dataSourceSnapshot
)
I get get a table that looks like this:
| dsRecordId | dsPropPropertyName | dsPropPropertyValue | dpPropertyName | dpPropertyValue |
--------------------------------------------------------------------------------------------------
| 1 | id | 1 | 1 | |
| 1 | description | cpu stats | 2 | |
| 1 | name | cpu | 3 | |
That does not look right, so I assume I am mis-using ROW_NUMBER() and OVER().
The question is, how do I get a pivoted row per datapoint, joined to (or joined from?) the datasourceProperty and datasourceSnapshot tables

SQL Count depending on certain conditions

I have two tables.
One have userid and email (users table). The other have payments information (payments table) from the userid in users.
users
+--------+------------+
| Userid | Name |
+--------+------------+
| 1 | Alex T |
| 2 | Jeremy T |
| 3 | Frederic A |
+--------+------------+
payments
+--------+-----------+------------+----------+
| Userid | ValuePaid | PaidMonths | Refunded |
+--------+-----------+------------+----------+
| 1 | 1 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 1 | null |
| 2 | 1 | 1 | null |
| 2 | 20 | 12 | 1 |
| 2 | 20 | 12 | null |
| 2 | 20 | 1 | null |
| 3 | 1 | 12 | null |
| 3 | 20 | 1 | 1 |
| 3 | 20 | 1 | null |
+--------+-----------+------------+----------+
I want to count the PaidMonths taking in consideration the following rules:
If ValuePaid < 10 PaidMonths should be = 0.23 (even if in the column the value seen is any other mumber).
If Refund=1 the PaidMonths should be = 0.
Based on this when i join both tables by userid, and sum the PaidMonths based in the previousrules, i expect to see as result:
+--------+------------+------------+
| userid | Name | paidMonths |
+--------+------------+------------+
| 1 | Alex T | 25.23 |
| 2 | Jeremy T | 13.23 |
| 3 | Frederic A | 1.23 |
+--------+------------+------------+
Can you help me to achieve this in the most elegant way? Should a temporary table be used?
The following gives your desired results, using apply with case expression to map your values:
select u.UserID, u.Name, Sum(pm) PaidMonths
from users u join payments p on p.userid=u.userid
cross apply (values(
case
when valuepaid <10 then 0.23
when Refunded=1 then 0
else PaidMonths end
))x(pm)
group by u.UserID, u.Name
See Working Fiddle

Moving data to correct record

I have a table where the data is needs to be corrected. Below is an example of one record. Basically the data in the selling closed_unit needs to be in the Agent_to_Agent Ref close_unit. I have tried every different what I can think of but I can't get it figured out. I am sure it is fairly simple I think I am just looking too hard at the wrong way. Any help is greatly appreciated!
Current (bad) data:
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
| sale_no | payeeID | ComType | close_units | record_type | ref_agent_type | referring_agentID | ref_side |
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
| 7586 | 1001 | Listing | 1 | Listing | NULL | 0 | |
| 7586 | 2001 | Selling | 1 | Selling | NULL | 0 | |
| 7586 | 3254 | NULL | 0 | Off The Top Ref | NULL | 0 | L |
| 7586 | 4684 | Agent to Agent Ref | 0 | Agent Paid Ref | Selling | 2001 | |
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
Expected result:
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
| sale_no | payeeID | ComType | close_units | record_type | ref_agent_type | referring_agentID | ref_side |
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
| 7586 | 1001 | Listing | 1 | Listing | NULL | 0 | |
| 7586 | 2001 | Selling | 0 | Selling | NULL | 0 | |
| 7586 | 3254 | NULL | 0 | Off The Top Ref | NULL | 0 | L |
| 7586 | 4684 | Agent to Agent Ref | 1 | Agent Paid Ref | Selling | 2001 | |
+---------+---------+--------------------+-------------+-----------------+----------------+-------------------+----------+
The following query will copy the value to the "Agent to Agent Ref" row:
update my_table t1 set close_units = (
select close_units from my_table t2
where t2.sale_no = t1.sale_no and t2.ComType = 'Selling'
)
where ComType = 'Agent to Agent Ref';
And this one will reset the "Selling" value to zero:
update my_table t1
set close_units = 0
where ComType = 'Selling'
and exists (
select close_units from my_table t2
where t2.sale_no = t1.sale_no and t2.ComType = 'Agent to Agent Ref'
)

Sum data from two tables with different number of rows

There are 3 Tables (SorMaster, SorDetail, and InvWarehouse):
SorMaster:
+------------+
| SalesOrder |
+------------+
| 100 |
| 101 |
| 102 |
+------------+
SorDetail:
+------------+------------+---------------+
| SalesOrder | MStockCode | MBackOrderQty |
+------------+------------+---------------+
| 100 | PN-1 | 4 |
| 100 | PN-2 | 9 |
| 100 | PN-3 | 1 |
| 100 | PN-4 | 6 |
| 101 | PN-1 | 6 |
| 101 | PN-3 | 2 |
| 102 | PN-2 | 19 |
| 102 | PN-3 | 14 |
| 102 | PN-4 | 6 |
| 102 | PN-5 | 4 |
+------------+------------+---------------+
InvWarehouse:
+------------+-----------+-----------+
| MStockCode | Warehouse | QtyOnHand |
+------------+-----------+-----------+
| PN-1 | A | 1 |
| PN-2 | B | 9 |
| PN-3 | A | 0 |
| PN-4 | B | 1 |
| PN-1 | A | 0 |
| PN-3 | B | 5 |
| PN-2 | A | 9 |
| PN-3 | B | 4 |
| PN-4 | A | 6 |
| PN-5 | B | 0 |
+------------+-----------+-----------+
Desired Results:
+------------+-----------------+--------------+
| MStockCode | SumBackOrderQty | SumQtyOnHand |
+------------+-----------------+--------------+
| PN-1 | 10 | 10 |
| PN-2 | 28 | 1 |
| PN-3 | 17 | 5 |
| PN-4 | 12 | 13 |
| PN-5 | 11 | 6 |
+------------+-----------------+--------------+
I have been going around in circles with no end in sight. Seems like it should be simple but just can't wrap my head around it. The SumBackOrderQty obviously getting counted twice as the SumQtyOnHand is evaluated. To this point I have been doing the calculations in the PHP instead of the select statement but would like to clean things up a bit where possible.
Current query statement is:
SELECT SorDetail.MStockCode,
SUM(SorDetail.MBackOrderQty) AS 'SumMBackOrderQty',
SUM(InvWarehouse.QtyOnHand) AS 'SumQtyOnHand'
FROM SysproCompanyJ.dbo.SorMaster SorMaster,
SysproCompanyJ.dbo.SorDetail SorDetail LEFT OUTER JOIN SysproCompanyJ.dbo.InvWarehouse InvWarehouse
ON SorDetail.MStockCode = InvWarehouse.StockCode
WHERE SorMaster.SalesOrder = SorDetail.SalesOrder
AND SorMaster.ActiveFlag != 'N'
AND SorDetail.MBackOrderQty > '0'
AND SorDetail.MPrice > '0'
GROUP BY SorDetail.MStockCode
ORDER BY SorDetail.MStockCode ASC
Without providing the complete picture, in terms of your RDBMS, database schema, a description of the problem you're trying to solve and sample data that matches the aforementioned, the following is just an illustration of what a solution based on Barmar's comment could look like:
SELECT SD.MStockCode,
SD.SumBackOrderQty,
IW.SumQtyOnHand
FROM (SELECT MStockCode,
SUM(MBackOrderQty) AS `SumBackOrderQty`
FROM SorDetail
JOIN SorMaster ON SorDetail.SalesOrder=SorMaster.SalesOrder
WHERE SorMaster.ActiveFlag != 'N'
AND SorDetail.MBackOrderQty > 0
AND SorDetail.MPrice > 0
GROUP BY MStockCode) AS SD
LEFT JOIN (SELECT MStockCode,
SUM(QtyOnHand) AS `SumQtyOnHand`
FROM InvWarehouse
GROUP BY MStockCode) AS IW ON SD.MStockCode=IW.MStockCode
ORDER BY SD.MStockCode;
Here's one approach:
select MStockCode,
(select sum(MBackOrderQty) from sorDetail as T2
where T2.MStockCode = T1.MStockCode ) as SumBackOrderQty,
(select sum(QtyOnHand) from invWarehouse as T3
where T3.MStockCode = T1.MStockCode ) as SumQtyOnHand
from
(
select mstockcode from sorDetail
union
select mstockcode from invWarehouse
) as T1
In a fiddle here: http://sqlfiddle.com/#!9/fdaca/6
Though my SumQtyOnHand values don't match yours (as #Gordon pointed out).

Joining two tables and calculating divide-SUM from the resulting table in SQL Server

I have one table that looks like this:
+---------------+---------------+-----------+-------+------+
| id_instrument | id_data_label | Date | Value | Note |
+---------------+---------------+-----------+-------+------+
| 1 | 57 | 1.10.2010 | 200 | NULL |
| 1 | 57 | 2.10.2010 | 190 | NULL |
| 1 | 57 | 3.10.2010 | 202 | NULL |
| | | | | |
+---------------+---------------+-----------+-------+------+
And the other that looks like this:
+----------------+---------------+---------------+--------------+-------+-----------+------+
| id_fundamental | id_instrument | id_data_label | quarter_code | value | AnnDate | Note |
+----------------+---------------+---------------+--------------+-------+-----------+------+
| 1 | 1 | 20 | 20101 | 3 | 28.2.2010 | NULL |
| 2 | 1 | 20 | 20102 | 4 | 1.8.2010 | NULL |
| 3 | 1 | 20 | 20103 | 5 | 2.11.2010 | NULL |
| | | | | | | |
+----------------+---------------+---------------+--------------+-------+-----------+------+
What I would like to do is to merge/join these two tables in one in a way that I get something like this:
+------------+--------------+--------------+----------+--------------+
| Date | Table1.Value | Table2.Value | AnnDate | quarter_code |
+------------+--------------+--------------+----------+--------------+
| 1.10.2010. | 200 | 3 | 1.8.2010 | 20102 |
| 2.10.2010. | 190 | 3 | 1.8.2010 | 20102 |
| 3.10.2010. | 202 | 3 | 1.8.2010 | 20102 |
| | | | | |
+------------+--------------+--------------+----------+--------------+
So the idea is to order them by Date from Table1 and since Table2 Values only change on the change of AnnDate we populate the Resulting table with same values from Table2.
After that I would like to go through the resulting table and create another (Final table) with the following.
On Date 1.10.2010. take last 4 AnnDates (so it would be 1.8.2010. and f.e. 20.3.2010. 30.1.2010. 15.11.2009) and Table2 values on those AnnDate. Make SUM of those 4 values and then divide the Table1 Value with that SUM.
So we would get something like:
+-----------+---------------------------------------------------------------+
| Date | FinalValue |
+-----------+---------------------------------------------------------------+
| 1.10.2010 | 200/(Table2.Value on 1.8.2010+Table2.Value on 20.3.2010 +...) |
| | |
+-----------+---------------------------------------------------------------+
Is there any way this can be done?
EDIT:
Hmm yes now I see that I really didn't do a good job explaining it.
What I wanted to say is
I try INNER JOIN like this:
SELECT TableOne.Date, TableOne.Value, TableTwo.Value, TableTwo.AnnDate, TableTwo.quarter_code
FROM TableOne
INNER JOIN TableTwo ON TableOne.id_intrument=TableTwo.id_instrument WHERE TableOne.id_data_label = somevalue AND TableTwo.id_data_label = somevalue AND date > xxx AND date < yyy
And this inner join returns 2620*40 rows which means for every AnnDate from table2 it returns all Date from table1.
What I want is to return 2620 values with Dates from Table1
Values from table1 on that date and Values from table2 that respond to that period of dates
f.e.
Table1:
+-------+-------+
| Date | Value |
+-------+-------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+-------+-------+
Table2
+-------+---------+
| Value | AnnDate |
+-------+---------+
| x | 1 |
| y | 4 |
+-------+---------+
Resulting table:
+-------+---------+---------+
| Date | ValueT1 | ValueT2 |
+-------+---------+---------+
| 1 | a | x |
| 2 | b | x |
| 3 | c | x |
| 4 | d | y |
+-------+---------+---------+
You need a JOIN statement for your first query. Try:
SELECT TableOne.Date, TableOne.Value, TableTwo.Value, TableTwo.AnnDate, TableTwo.quarter_code FROM TableOne
INNER JOIN TableTwo
ON TableOne.id_intrument=TableTwo.id_instrument;