SQL Server joining trouble - sql

Scenario:
I am trying to build a query which has a start and end date, And the result of this query gives me the days in between and the day name. I then want to JOIN to another table which has expected pay dates and amounts. The JOINED table may have more days outside the range of the start and end date, which I want to exclude.
Progress:
I sort-of have what I want, but not in the correct output, I have created the following thus far:
DECLARE
#startDate DATETIME,
#endDate DATETIME
SET #startDate = CONVERT(VARCHAR(4), DATEPART(YEAR, DATEADD(MONTH, -1, GETDATE())))+'-'+CONVERT(VARCHAR(2), DATEPART(MONTH, DATEADD(MONTH, -1, GETDATE())))+'-21'
SET #endDate = CONVERT(VARCHAR(4), DATEPART(YEAR, DATEADD(MONTH, -1, GETDATE())))+'-'+CONVERT(VARCHAR(2), DATEPART(MONTH, DATEADD(MONTH, -0, GETDATE())))+'-20'
;WITH dates AS
(
SELECT #startdate as Date,DATENAME(Dw,#startdate) As DayName
UNION ALL
SELECT DATEADD(d,1,[Date]),DATENAME(Dw,DATEADD(d,1,[Date])) as DayName
FROM dates
WHERE DATE < #enddate
)
SELECT LEFT(CONVERT(VARCHAR(30),Date, 106), 2) + '-' + LEFT(CONVERT(VARCHAR(30),Date, 10), 2) Date,DayName, SUM(ExpectedAmount), ExpectedDate FROM dates
FULL JOIN Commissions.dbo.ThreeMonthPayment on CONVERT(VARCHAR(30),Date) = Commissions.dbo.ThreeMonthPayment.ExpectedDate
GROUP BY Date, DayName, ExpectedDate
Order by ExpectedDate
Which results in this table (Sorry so long):
+-------+-----------+------------------+--------------+
| Date | DayName | (No column name) | ExpectedDate |
+-------+-----------+------------------+--------------+
| NULL | NULL | 0 | NULL |
| 21-03 | Friday | NULL | NULL |
| 22-03 | Saturday | NULL | NULL |
| 23-03 | Sunday | NULL | NULL |
| 24-03 | Monday | NULL | NULL |
| 25-03 | Tuesday | NULL | NULL |
| 26-03 | Wednesday | NULL | NULL |
| 27-03 | Thursday | NULL | NULL |
| 28-03 | Friday | NULL | NULL |
| 29-03 | Saturday | NULL | NULL |
| 30-03 | Sunday | NULL | NULL |
| 31-03 | Monday | NULL | NULL |
| 01-04 | Tuesday | NULL | NULL |
| 02-04 | Wednesday | NULL | NULL |
| 03-04 | Thursday | NULL | NULL |
| 04-04 | Friday | NULL | NULL |
| 05-04 | Saturday | NULL | NULL |
| 06-04 | Sunday | NULL | NULL |
| 07-04 | Monday | NULL | NULL |
| 08-04 | Tuesday | NULL | NULL |
| 09-04 | Wednesday | NULL | NULL |
| 10-04 | Thursday | NULL | NULL |
| 11-04 | Friday | NULL | NULL |
| 12-04 | Saturday | NULL | NULL |
| 13-04 | Sunday | NULL | NULL |
| 14-04 | Monday | NULL | NULL |
| 15-04 | Tuesday | NULL | NULL |
| 16-04 | Wednesday | NULL | NULL |
| 17-04 | Thursday | NULL | NULL |
| 18-04 | Friday | NULL | NULL |
| 19-04 | Saturday | NULL | NULL |
| 20-04 | Sunday | NULL | NULL |
| NULL | NULL | 89466 | 01-03 |
| NULL | NULL | 86058 | 01-04 |
| NULL | NULL | 23356 | 01-05 |
| NULL | NULL | 1858 | 01-06 |
| NULL | NULL | 13597 | 02-03 |
| NULL | NULL | 55587 | 02-04 |
| NULL | NULL | 7857 | 02-05 |
| NULL | NULL | 1377 | 02-06 |
| NULL | NULL | 6947 | 03-03 |
| NULL | NULL | 49626 | 03-04 |
| NULL | NULL | 0 | 03-05 |
| NULL | NULL | 0 | 03-06 |
| NULL | NULL | 6054 | 04-03 |
| NULL | NULL | 31639 | 04-04 |
| NULL | NULL | 0 | 04-05 |
| NULL | NULL | 0 | 04-06 |
| NULL | NULL | 26421 | 05-03 |
| NULL | NULL | 28154 | 05-04 |
| NULL | NULL | 15036 | 05-05 |
| NULL | NULL | 634 | 05-06 |
| NULL | NULL | 0 | 05-07 |
| NULL | NULL | 20832 | 06-03 |
| NULL | NULL | 0 | 06-04 |
| NULL | NULL | 0 | 06-05 |
| NULL | NULL | 0 | 06-06 |
| NULL | NULL | 5406 | 07-03 |
| NULL | NULL | 12864 | 07-04 |
| NULL | NULL | 4257 | 07-05 |
| NULL | NULL | 537 | 07-06 |
| NULL | NULL | 0 | 08-03 |
| NULL | NULL | 363 | 08-04 |
| NULL | NULL | 426 | 08-05 |
| NULL | NULL | 0 | 08-06 |
| NULL | NULL | 0 | 09-03 |
| NULL | NULL | 23240 | 09-04 |
| NULL | NULL | 0 | 09-05 |
| NULL | NULL | 0 | 09-06 |
| NULL | NULL | 12670 | 10-03 |
| NULL | NULL | 6790 | 10-04 |
| NULL | NULL | 0 | 10-05 |
| NULL | NULL | 0 | 10-06 |
| NULL | NULL | 2914 | 11-03 |
| NULL | NULL | 19053 | 11-04 |
| NULL | NULL | 0 | 11-05 |
| NULL | NULL | 0 | 11-06 |
| NULL | NULL | 6402 | 12-03 |
| NULL | NULL | 0 | 12-04 |
| NULL | NULL | 0 | 12-05 |
| NULL | NULL | 0 | 12-06 |
| NULL | NULL | 4166 | 13-03 |
| NULL | NULL | 0 | 13-04 |
| NULL | NULL | 0 | 13-05 |
| NULL | NULL | 0 | 13-06 |
| NULL | NULL | 50534 | 14-03 |
| NULL | NULL | 23854 | 14-04 |
| NULL | NULL | 15435 | 14-05 |
| NULL | NULL | 4003 | 14-06 |
| NULL | NULL | 475330 | 15-03 |
| NULL | NULL | 451014 | 15-04 |
| NULL | NULL | 103210 | 15-05 |
| NULL | NULL | 19947 | 15-06 |
| NULL | NULL | 12084 | 16-03 |
| NULL | NULL | 22203 | 16-04 |
| NULL | NULL | 517 | 16-05 |
| NULL | NULL | 0 | 16-06 |
| NULL | NULL | 31423 | 17-03 |
| NULL | NULL | 32150 | 17-04 |
| NULL | NULL | 0 | 17-05 |
| NULL | NULL | 0 | 17-06 |
| NULL | NULL | 33402 | 18-03 |
| NULL | NULL | 900 | 18-04 |
| NULL | NULL | 289 | 18-05 |
| NULL | NULL | 0 | 18-06 |
| NULL | NULL | 33929 | 19-03 |
| NULL | NULL | 6942 | 19-04 |
| NULL | NULL | 0 | 19-05 |
| NULL | NULL | 0 | 19-06 |
| NULL | NULL | 161806 | 20-03 |
| NULL | NULL | 141319 | 20-04 |
| NULL | NULL | 26659 | 20-05 |
| NULL | NULL | 4695 | 20-06 |
| NULL | NULL | 21074 | 21-03 |
| NULL | NULL | 15579 | 21-04 |
| NULL | NULL | 2693 | 21-05 |
| NULL | NULL | 0 | 21-06 |
| NULL | NULL | 28401 | 22-03 |
| NULL | NULL | 46258 | 22-04 |
| NULL | NULL | 11409 | 22-05 |
| NULL | NULL | 1672 | 22-06 |
| NULL | NULL | 76562 | 23-03 |
| NULL | NULL | 66804 | 23-04 |
| NULL | NULL | 32853 | 23-05 |
| NULL | NULL | 3168 | 23-06 |
| NULL | NULL | 47008 | 24-03 |
| NULL | NULL | 35888 | 24-04 |
| NULL | NULL | 4528 | 24-05 |
| NULL | NULL | 459 | 24-06 |
| NULL | NULL | 1108747 | 25-03 |
| NULL | NULL | 543351 | 25-04 |
| NULL | NULL | 152852 | 25-05 |
| NULL | NULL | 15712 | 25-06 |
| NULL | NULL | 343379 | 26-03 |
| NULL | NULL | 117657 | 26-04 |
| NULL | NULL | 41793 | 26-05 |
| NULL | NULL | 5645 | 26-06 |
| NULL | NULL | 0 | 27-02 |
| NULL | NULL | 401110 | 27-03 |
| NULL | NULL | 87571 | 27-04 |
| NULL | NULL | 39192 | 27-05 |
| NULL | NULL | 2801 | 27-06 |
| NULL | NULL | 313274 | 28-03 |
| NULL | NULL | 92607 | 28-04 |
| NULL | NULL | 21901 | 28-05 |
| NULL | NULL | 1852 | 28-06 |
| NULL | NULL | 77999 | 29-03 |
| NULL | NULL | 27693 | 29-04 |
| NULL | NULL | 3341 | 29-05 |
| NULL | NULL | 0 | 29-06 |
| NULL | NULL | 229556 | 30-03 |
| NULL | NULL | 261036 | 30-04 |
| NULL | NULL | 9109 | 30-05 |
| NULL | NULL | 545 | 30-06 |
| NULL | NULL | 460871 | 31-03 |
| NULL | NULL | 28710 | 31-05 |
+-------+-----------+------------------+--------------+
Out of the above results, I am trying to match the ExpectedDate to the date column , so instead of seeing the above results, I would have something that looks like this: (to keep it short, i haven't created all of the days I receive from my start and end date)
+-------+-----------+------------------+--------------+
| Date | DayName | (No column name) | ExpectedDate |
+-------+-----------+------------------+--------------+
| NULL | NULL | 0 | NULL |
| 21-03 | Friday | 21074 | 21-03 |
| 22-03 | Saturday | 28401 | 22-03 |
| 23-03 | Sunday | 76562 | 23-03 |
| 24-03 | Monday | 47008 | 24-03 |
+-------+-----------+------------------+--------------+
But you can see above that the expectedDate and date column are grouped / joined nicely together. And the expectedDates that are not in the date range are not displayed.
I have been struggling with this the entire morning :( is this possible ??
Any help or links to threads that I may have missed would be great!
I am using SQL SERVER 2008
Thanks so much.

first of all the full join includes everything. from both tables. if you only want the dates from the dates cte, use left join.
secondly, the CONVERT(VARCHAR(30),Date) = Commissions.dbo.ThreeMonthPayment.ExpectedDate seems to not work. are you sure you need to convert?
i suggest you try this:
DECLARE
#startDate DATETIME,
#endDate DATETIME
SET #startDate = CONVERT(VARCHAR(4), DATEPART(YEAR, DATEADD(MONTH, -1, GETDATE())))+'-'+CONVERT(VARCHAR(2), DATEPART(MONTH, DATEADD(MONTH, -1, GETDATE())))+'-21'
SET #endDate = CONVERT(VARCHAR(4), DATEPART(YEAR, DATEADD(MONTH, -1, GETDATE())))+'-'+CONVERT(VARCHAR(2), DATEPART(MONTH, DATEADD(MONTH, -0, GETDATE())))+'-20'
;WITH dates AS
(
SELECT #startdate as Date,DATENAME(Dw,#startdate) As DayName
UNION ALL
SELECT DATEADD(d,1,[Date]),DATENAME(Dw,DATEADD(d,1,[Date])) as DayName
FROM dates
WHERE DATE < #enddate
)
SELECT LEFT(CONVERT(VARCHAR(30),Date, 106), 2) + '-' + LEFT(CONVERT(VARCHAR(30),Date, 10), 2) Date
, DayName, SUM(ExpectedAmount), ExpectedDate
FROM dates
LEFT JOIN Commissions.dbo.ThreeMonthPayment
on Date = Commissions.dbo.ThreeMonthPayment.ExpectedDate
GROUP BY
Date
, DayName
, ExpectedDate
Order by
ExpectedDate

Related

SQL MAX() function seems to truncate results

I have the following basic 3 Table Structure in mariadb/mysql.
MariaDB [aix_registry]> describe nodes;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(256) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.036 sec)
MariaDB [aix_registry]> describe attribs;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(256) | NO | | NULL | |
| persistent | int(11) | YES | | 0 | |
| parent | varchar(256) | YES | | NODE | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.042 sec)
MariaDB [aix_registry]> describe entries;
+-----------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| node_id | int(11) | NO | MUL | NULL | |
| attrib_id | int(11) | NO | MUL | NULL | |
| value | varchar(256) | NO | | NULL | |
| ts | timestamp | NO | | current_timestamp() | |
+-----------+--------------+------+-----+---------------------+----------------+
5 rows in set (0.052 sec)
This simple SELECT returns incomplete records. I reduced the output of all follwing examples to a single dataset to avoid unnecessary clutter.
SELECT nodes.id AS NODE_ID, nodes.name AS NODE ,
MAX(CASE WHEN attribs.name = 'IP_LONG' THEN value END) AS IP_LONG,
MAX(CASE WHEN attribs.name = 'IP' THEN value END) AS IP,
MAX(CASE WHEN attribs.name = 'LOCATION' THEN value END) AS LOCATION
from entries left join nodes on nodes.id = node_id left join attribs on attribs.id = attrib_id WHERE entries.ts > DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP BY nodes.name ORDER BY nodes.id ;
+---------+-------------+-------------------------------------------+--------------+------------+
| NODE_ID | NODE | IP_LONG | IP | LOCATION |
+---------+-------------+-------------------------------------------+--------------+------------+
| 31 | AIXDX4-TEST | 172.17.9.196/255.255.248.0/172.17.15.255/ | 172.17.9.196 | Wienerberg |
+---------+-------------+-------------------------------------------+--------------+------------+
The IP_LONG column is missing the follwing for example...
172.16.84.74/255.255.192.0/172.16.127.255/aixdx4-test.domain.org
My guess is, it has something to do with the MAX() Function has troubles with mixed Content in the Value Column. When leaving out MAX() and GROUP BY the missing Values are shown but Output is kind of chaotic.
SELECT nodes.id AS NODE_ID, nodes.name AS NODE,
CASE WHEN attribs.name = 'IP_LONG' THEN value END AS IP_LONG,
CASE WHEN attribs.name = 'IP' THEN value END AS IP,
CASE WHEN attribs.name = 'LOCATION' THEN value END AS LOCATION
from entries left join nodes on nodes.id = node_id left join attribs on attribs.id = attrib_id
WHERE entries.ts > DATE_SUB(NOW(), INTERVAL 1 DAY) ORDER BY nodes.id;
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | 172.17.9.196 | NULL |
| 31 | AIXDX4-TEST | 172.17.9.196/255.255.248.0/172.17.15.255/ | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | 172.16.84.74 | NULL |
| 31 | AIXDX4-TEST | 172.16.84.74/255.255.192.0/172.16.127.255/aixdx4-test.domain.org | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | 172.16.13.196 | NULL |
| 31 | AIXDX4-TEST | 172.16.13.196/255.255.254.0/172.16.13.255/ | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | Wienerberg |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL | NULL | NULL |
| 31 | AIXDX4-TEST | NULL
This Query gives the right Output, but i am unclear how to integrate that in the above, but this is a Topic for another question.
SELECT nodes.id AS NODE_ID, nodes.name AS NODE, entries.value
AS IP_NETMASK_BROADCAST_DNS
FROM (entries LEFT JOIN nodes ON(nodes.id = entries.node_id))
WHERE entries.attrib_id = (SELECT attribs.id FROM attribs WHERE attribs.name = 'IP_LONG') AND CAST(entries.ts AS date) = curdate() AND nodes.id = '31' ORDER BY nodes.name;
+---------+-------------+------------------------------------------------------------------+
| NODE_ID | NODE | IP_NETMASK_BROADCAST_DNS |
+---------+-------------+------------------------------------------------------------------+
| 31 | AIXDX4-TEST | 172.17.9.196/255.255.248.0/172.17.15.255/ |
| 31 | AIXDX4-TEST | 172.16.84.74/255.255.192.0/172.16.127.255/aixdx4-test.domain.org |
| 31 | AIXDX4-TEST | 172.16.13.196/255.255.254.0/172.16.13.255/ |
+---------+-------------+------------------------------------------------------------------+
These are the 3 values you are getting a max() of
172.17.9.196/255.255.248.0/172.17.15.255/
172.16.84.74/255.255.192.0/172.16.127.255/aixdx4-test.domain.org
172.16.13.196/255.255.254.0/172.16.13.255/
These are strings -- max looks at a "alphabetical" max. Since the "9" is greater than the 8 and the 1 the first one 172.17.9.196/255.255.248.0/172.17.15.255/ is picked. These values are all different -- which do you want and why? Do you want the longest one? The longest one would require different code.

Select all columns with only two distinct columns

In my SQL Server database, I have a table with many duplicate values and I need to fetch results with distinct columns EID and YEAR and select rows containing fewer NULL values or order the table and get a final DISTINCT column EID and YEAR rows.
For example: below the table with EID = E138442 and YEAR = 2019 occurs 21 times were in this duplicate the row containing fewer null values should be fetched
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| EID | YEAR | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC |
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| E050339 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
| E050339 | 2020 | NULL | 6 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E050339 | 2020 | 13 | 6 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138348 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 | NULL |
| E138348 | 2019 | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| e138372 | 2019 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138440 | 2019 | NULL | NULL | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | NULL | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | NULL | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | NULL | 7 | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | NULL | 7 | 7 | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | NULL | 1 | 7 | 7 | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2019 | NULL | 1 | NULL | 7 | 7 | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2020 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
| E138442 | 2020 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
| E138442 | 2020 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
| E138442 | 2020 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
I need a SQL query to fetch values as shown here:
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| EID | YEAR | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC |
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| E050339 | 2020 | 13 | 6 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138348 | 2019 | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| e138372 | 2019 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138440 | 2019 | NULL | NULL | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| E138442 | 2019 | NULL | 1 | NULL | 7 | 7 | 2 | 7 | 7 | 4 | 4 | 9 | 5 |
| E138442 | 2020 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 1 |
+---------+------+------+------+------+------+------+------+------+------+------+------+------+------+
The result table should have a final row with distinct columns EID and YEAR.
SELECT *
FROM TABLE_NAME C1
WHERE EXISTS (SELECT 1
FROM TABLE_NAME C2
WHERE C1.EID = C2.EID AND C1.YEAR = C2.YEAR
HAVING COUNT(*) = 1)
ORDER BY
c1.EID, c1.YEAR, c1.JAN, c1.FEB, c1.MAR, c1.APR,
c1.MAY, c1.JUN, c1.JUL, c1.AUG, c1.SEP, c1.OCT, c1.NOV, c1.DEC ASC;
I tried the above code but found irrelevant results
since you have no other way to distinguish members of a group and based on "select rows containing fewer NULL values " here is one way how you can do it by using ctes, its not clean but probably the only way:
with cte as (
SELECT *,
ISNULL(c1.JAN, 1) + ISNULL(c1.FEB,1) + ... + ISNULL(c1.DEC,1) AS NullCount
FROM
tablename
)
, cte2 as (
select EID , YEAR , min(NullCount) min_nullcount
from cte
group by EID , YEAR
)
select t.*
from
cte t
join cte2 tt
on t.EID = tt.EID
and t.YEAR = tt.YEAR
and t.NULLCount = tt.min_nullcount
If you have duplicate minimum null per group you can use query below :
select * from (
SELECT *,
ROW_NUMBER OVER (partition by EID , YEAR order by ISNULL(c1.JAN, 1) + ... + ISNULL(c1.DEC,1) AS rnk
FROM
tablename
) xx
WHERE rnk = 1

SQL Server - group by column for each corresponding value

I am new to this forum. Hope fully I will be able to contribute and get my queries resolved too.
I am stuck at this that I do not know where to start off.
I have below data set.
| Start Step| End 1 | End 2 |
| 1001866 | 1001867 | NULL |
| 1001866 | 1001868 | NULL |
| 1001868 | 1001873 | NULL |
| 1001873 | 1001868 | NULL |
| 1001868 | 1005206 | NULL |
| 1001873 | 1001867 | NULL |
| 1005206 | 1001873 | NULL |
| 1005206 | 1005385 | 1005386 |
| 1005206 | 1005377 | 1005378 |
| 1005378 | 1005376 | 1005206 |
| 1005379 | 1005376 | 1005206 |
| 1005379 | 1005380 | 1005381 |
| 1005381 | 1005382 | 1001869 |
| 1005381 | 1005383 | NULL |
| 1005381 | 1005384 | 1001872 |
| 1005378 | 1005379 | NULL |
| 1005383 | 1001872 | NULL |
| 1005383 | 1005376 | 1005206 |
| 1005383 | 1005381 | NULL |
| 1001869 | 1001871 | NULL |
| 1005386 | 1005376 | 1005206 |
I want each step to be in single row with their corresponding end1 and end2 and ordered by step and ranked. I want the output to be as in the image:
| Rank | Start | End Step 1 | End Step 2 |
| 1 | 1001866 | 1001867 | NULL |
| 1 | 1001866 | 1001868 | NULL |
| 2 | 1001867 | NULL | NULL |
| 3 | 1001868 | 1001873 | NULL |
| 3 | 1001868 | 1005206 | NULL |
| 4 | 1001869 | NULL | NULL |
| 4 | 1001869 | 1001871 | NULL |
| 5 | 1001871 | NULL | NULL |
| 6 | 1001872 | NULL | NULL |
| 7 | 1001873 | 1001868 | NULL |
| 7 | 1001873 | 1001867 | NULL |
| 8 | 1005206 | 1001873 | NULL |
| 8 | 1005206 | 1005385 | 1005386 |
| 8 | 1005206 | 1005377 | 1005378 |
| 9 | 1005376 | NULL | NULL |
| 10 | 1005377 | NULL | NULL |
| 11 | 1005378 | 1005379 | NULL |
| 11 | 1005378 | 1005376 | 1005206 |
| 12 | 1005379 | 1005376 | 1005206 |
| 12 | 1005379 | 1005380 | 1005381 |
| 13 | 1005380 | NULL | NULL |
| 14 | 1005381 | 1005382 | 1001869 |
| 14 | 1005381 | 1005383 | NULL |
| 14 | 1005381 | 1005384 | 1001872 |
| 15 | 1005382 | NULL | NULL |
| 16 | 1005383 | 1001872 | NULL |
| 16 | 1005383 | 1005376 | 1005206 |
| 16 | 1005383 | 1005381 | NULL |
| 17 | 1005384 | NULL | NULL |
| 18 | 1005385 | NULL | NULL |
| 19 | 1005386 | 1005376 | 1005206 |
| 19 | 1005386 | 1005387 | NULL |
| 20 | 1005387 | NULL | NULL |
Just highlighted few values for better understanding.
Is it possible ?
Can any one please help ?
select dense_rank() over(order by [start step]) [rank], * from
(select * from yourtable
union
select distinct [end 1], null, null from yourtable where [end 1] is not null
union
select distinct [end 2], null, null from yourtable where [end 2] is not null
)a order by [start step]

Joining two selects into 4 columns

I am trying to join two select statements to form 4 columns in one table. My desired result would be something like this
+--------------+----------------+------------------+--------------+
| ExpectedDate | ExpectedAmount | ActualDate | ActualAmount |
+--------------+----------------+------------------+--------------+
| 01/03/2014 | 65161 | 2014-03-01 00:00 | 57 |
| 02/03/2014 | 64 | 2014-03-02 00:00 | 321651651 |
| 03/03/2014 | 8 | 2014-03-03 00:00 | 233258646 |
| 04/03/2014 | 561 | 2014-03-04 00:00 | 2321 |
| 05/03/2014 | 651651 | 2014-03-05 00:00 | 8494561 |
| 06/03/2014 | 651616131 | NULL | NULL |
| 07/03/2014 | 316548478 | NULL | NULL |
| 08/03/2014 | 646512132 | NULL | NULL |
| 10/03/2014 | 654984984 | NULL | NULL |
| 11/03/2014 | 323213218 | NULL | NULL |
| 12/03/2014 | 6464651 | NULL | NULL |
| 13/03/2014 | 313218 | NULL | NULL |
| 14/03/2014 | 849898 | NULL | NULL |
| 15/03/2014 | 3213218 | NULL | NULL |
| 16/03/2014 | 9898465 | NULL | NULL |
+--------------+----------------+------------------+--------------+
I have the following SQL at the moment, which is very close, but instead of being in the same rows, they are split up like this:
+--------------+----------------+------------------+--------------+
| ExpectedDate | ExpectedAmount | ActualDate | ActualAmount |
+--------------+----------------+------------------+--------------+
| 01/03/2014 | 65161 | NULL | NULL |
| 02/03/2014 | 64 | NULL | NULL |
| 03/03/2014 | 8 | NULL | NULL |
| 04/03/2014 | 561 | NULL | NULL |
| 05/03/2014 | 651651 | NULL | NULL |
| 06/03/2014 | 651616131 | NULL | NULL |
| 07/03/2014 | 316548478 | NULL | NULL |
| 08/03/2014 | 646512132 | NULL | NULL |
| 10/03/2014 | 654984984 | NULL | NULL |
| 11/03/2014 | 323213218 | NULL | NULL |
| 12/03/2014 | 6464651 | NULL | NULL |
| 13/03/2014 | 313218 | NULL | NULL |
| 14/03/2014 | 849898 | NULL | NULL |
| 15/03/2014 | 3213218 | NULL | NULL |
| 16/03/2014 | 9898465 | NULL | NULL |
| NULL | NULL | 2014-03-01 00:00 | 57 |
| NULL | NULL | 2014-03-02 00:00 | 321651651 |
| NULL | NULL | 2014-03-03 00:00 | 233258646 |
| NULL | NULL | 2014-03-04 00:00 | 2321 |
| NULL | NULL | 2014-03-05 00:00 | 8494561 |
+--------------+----------------+------------------+--------------+
Here is the SQL:
--DECLARE PERIOD
DECLARE #NextMonthDate VARCHAR(10)
DECLARE #currentMonthDate VARCHAR(10)
DECLARE #VarientVar VARCHAR(10)
DECLARE #ExpectedDateSample VARCHAR(10)
--SET PERIOD
SET #NextMonthDate = CONVERT(VARCHAR(4), DATEPART(YEAR, DATEADD(MONTH, -1, GETDATE())))+'-'+SUBSTRING(CONVERT(VARCHAR, DATEADD(MONTH, +1, GETDATE()), 112),5,2)
SET #currentMonthDate = CONVERT(VARCHAR(4), DATEPART(YEAR, GETDATE()))+'-'+SUBSTRING(CONVERT(VARCHAR, DATEADD(MONTH, +0, GETDATE()), 112),5,2)
SET #ExpectedDateSample = SUBSTRING(CONVERT(VARCHAR, DATEADD(MONTH, +0, GETDATE()), 112),5,2)+'/'+CONVERT(VARCHAR(4), DATEPART(YEAR, GETDATE()))
SELECT e.ExpectedDate, e.ExpectedAmount, a.ActualDate, a.ActualAmount
FROM (SELECT ExpectedDate, SUM(ExpectedPayment) ExpectedAmount
FROM Simplicity..V_PaymentPlan2
WHERE Period >= #currentMonthDate and Period < #NextMonthDate AND HyphenStatus != 'Unpaid' AND ExpectedDate LIKE '%'+#ExpectedDateSample+'%'
GROUP BY ExpectedDate) e
FULL JOIN
(SELECT CONVERT(VARCHAR, PaymentDate, 20) ActualDate, SUM(ActualPayment) ActualAmount
FROM Simplicity..V_PaymentPlan2
WHERE Period >= #currentMonthDate and Period < #NextMonthDate AND HyphenStatus != 'Unpaid' AND CONVERT(VARCHAR, PaymentDate, 20) LIKE '%'+#currentMonthDate+'%'
GROUP BY PaymentDate) a on a.ActualDate = e.ExpectedDate
ORDER BY e.ExpectedDate, a.ActualDate
Any idea how to make them line up in the same rows instead of inserting NULL and pushing them down?
I dont have any Primary Key or Foreign Key.
SELECT ExpectedDate,ExpectedAmount, ActualDate, ActualAmount FROM A a1
INNER JOIN A a2
ON a1.ExpectedDate = a2.ActualDate

MySQL ignores my index

I'm running the following query in MYSQL
select distinct straight_join
cu.entryid entryid,
t0.tokpos starting_position,
t3.tokpos ending_position,
t0.idxsent idxsent,
'TOKENS_44_340' tablename
from
TOKENS_44_340 t0,
constraints_appraisal cu,
TOKENS_44_340 t1,
TOKENS_44_340 t2,
TOKENS_44_340 t3
where
t0.token_surface = cu.token_0
and (cu.pos_0 is null OR t0.penntag like concat(cu.pos_0,'%'))
and t1.token_surface = cu.token_1
and (cu.pos_1 is null OR t1.penntag like concat(cu.pos_1,'%'))
and t2.token_surface = cu.token_2
and (cu.pos_2 is null OR t2.penntag like concat(cu.pos_2,'%'))
and t3.token_surface = cu.token_3
and (cu.pos_3 is null OR t3.penntag like concat(cu.pos_3,'%'))
and t0.tokpos = t1.tokpos - 1
and t1.tokpos = t2.tokpos - 1
and t2.tokpos = t3.tokpos - 1
and cu.token_4 is null
and cu.token_5 is null
and cu.token_6 is null
and cu.token_7 is null
and cu.token_8 is null
and cu.token_9 is null;
MySQL gives me the following query plan for this query:
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
| 1 | SIMPLE | t0 | ALL | PRIMARY,TOKENS_44_340_index_44,tokpos | NULL | NULL | NULL | 49 | Using temporary |
| 1 | SIMPLE | cu | ALL | NULL | NULL | NULL | NULL | 7907 | Using where |
| 1 | SIMPLE | t1 | ref | PRIMARY,TOKENS_44_340_index_44,tokpos | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
| 1 | SIMPLE | t2 | ref | PRIMARY,TOKENS_44_340_index_44,tokpos | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
| 1 | SIMPLE | t3 | ref | TOKENS_44_340_index_44 | TOKENS_44_340_index_44 | 399 | func | 4 | Using where |
+----+-------------+-------+------+---------------------------------------+------------------------+---------+------+------+-----------------+
5 rows in set (0.00 sec)
As you can see, MySQL doesn't even so much as acknowledge the existance of my index token_0 on constraints_appraisal(token_0). Any idea why it's ignoring my index, and what I can do about it? I'm running mysql 5.0.51a-24+lenny4 for Debian stable.
P.S. I know I could make this query run faster by removing the straight_join constraint and let it use the token_surface index on t0, but it still wouldn't be as fast as it could be using the token_0 index on constraints_appraisal. I added the straight_join so that I could make my specific issue appear more clearly, and I plan remove it when I have the index working properly.
mysql> describe TOKENS_44_340;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| tokPos | int(11) | NO | PRI | NULL | |
| linePos | int(11) | YES | | NULL | |
| EOLs | int(11) | YES | | NULL | |
| idxsent | int(11) | YES | | NULL | |
| possent | int(11) | YES | | NULL | |
| brilltag | int(11) | YES | | NULL | |
| token_surface | varchar(132) | YES | MUL | NULL | |
| wordLen | int(11) | YES | | NULL | |
| capitalized | int(11) | YES | | NULL | |
| wordType | int(11) | YES | | NULL | |
| numDigit | int(11) | YES | | NULL | |
| numPunc | int(11) | YES | | NULL | |
| numAlpha | int(11) | YES | | NULL | |
| maxRep | int(11) | YES | | NULL | |
| pre1 | varchar(132) | YES | | NULL | |
| pre2 | varchar(132) | YES | | NULL | |
| pre3 | varchar(132) | YES | | NULL | |
| pre4 | varchar(132) | YES | | NULL | |
| suf1 | varchar(132) | YES | | NULL | |
| suf2 | varchar(132) | YES | | NULL | |
| suf3 | varchar(132) | YES | | NULL | |
| suf4 | varchar(132) | YES | | NULL | |
| dep_gov | int(11) | YES | MUL | NULL | |
| dep_rel | varchar(20) | YES | MUL | NULL | |
| penntag | varchar(30) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
25 rows in set (0.04 sec)
mysql> describe constraints_appraisal;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| entryid | int(11) | NO | PRI | 0 | |
| context | varchar(50) | YES | | NULL | |
| syntax | int(11) | YES | | NULL | |
| token_0 | varchar(50) | YES | MUL | NULL | |
| pos_0 | varchar(50) | YES | | NULL | |
| porter_0 | varchar(50) | YES | MUL | NULL | |
| token_1 | varchar(50) | YES | | NULL | |
| pos_1 | varchar(50) | YES | | NULL | |
| porter_1 | varchar(50) | YES | | NULL | |
| token_2 | varchar(50) | YES | | NULL | |
| pos_2 | varchar(50) | YES | | NULL | |
| porter_2 | varchar(50) | YES | | NULL | |
| token_3 | varchar(50) | YES | | NULL | |
| pos_3 | varchar(50) | YES | | NULL | |
| porter_3 | varchar(50) | YES | | NULL | |
| token_4 | varchar(50) | YES | | NULL | |
| pos_4 | varchar(50) | YES | | NULL | |
| porter_4 | varchar(50) | YES | | NULL | |
| token_5 | varchar(50) | YES | | NULL | |
| pos_5 | varchar(50) | YES | | NULL | |
| porter_5 | varchar(50) | YES | | NULL | |
| token_6 | varchar(50) | YES | | NULL | |
| pos_6 | varchar(50) | YES | | NULL | |
| porter_6 | varchar(50) | YES | | NULL | |
| token_7 | varchar(50) | YES | | NULL | |
| pos_7 | varchar(50) | YES | | NULL | |
| porter_7 | varchar(50) | YES | | NULL | |
| token_8 | varchar(50) | YES | | NULL | |
| pos_8 | varchar(50) | YES | | NULL | |
| porter_8 | varchar(50) | YES | | NULL | |
| token_9 | varchar(50) | YES | | NULL | |
| pos_9 | varchar(50) | YES | | NULL | |
| porter_9 | varchar(50) | YES | | NULL | |
| token_surface | varchar(200) | YES | | NULL | |
| fileid | varchar(100) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
35 rows in set (0.06 sec)
mysql> show index from constraints_appraisal;
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| constraints_appraisal | 0 | PRIMARY | 1 | entryid | A | 7907 | NULL | NULL | | BTREE | |
| constraints_appraisal | 1 | token_0 | 1 | token_0 | A | NULL | NULL | NULL | YES | BTREE | |
| constraints_appraisal | 1 | porter_0 | 1 | porter_0 | A | NULL | NULL | NULL | YES | BTREE | |
+-----------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.05 sec)
It appears that the problem is that the two tables are in different character sets.
TOKENS_44_340 is in utf8
constraints_appraisal is in latin1