Merge Rows in SQL Table based on two table values - sql

I have a table with travel details. Details are getting saved in distributed manner. I need to merge the rows based on Source and Destination. My Source is A and Final Destination is D, I need to merge all the 3 rows into 1 with sum of time and distance, based on date of travel.
Table Details and Expected Output
I tried using Concatenate but not able to do based on conditions. Not sure how to combine rows of one table based on values of another.

You can use LEFT JOIN statement and then aggregate:
SELECT Table2.Date,
Table2.CarID,
Table2.Source,
Table2.Destination,
SUM(Table1.Distance) AS Distance,
SUM(Table1.[Time(Hours)]) AS [Time(Hours)]
FROM Table2
LEFT JOIN Table1
ON (Table1.Source BETWEEN Table2.Source AND Table2.Destination
OR Table1.Destination BETWEEN Table2.Source AND Table2.Destination)
AND Table2.Date = Table1.Date
AND Table2.CarID = Table1.CarID
GROUP BY Table2.Date,
Table2.CarID,
Table2.Source,
Table2.Destination
This assumes that your Source and Destination never overlap - like in the example you provided.

Related

Postgresql Joining Time Series With Missing Data

I am trying to outer join multiple time series tables in PostgreSQL on multiple conditions - which include the date column and several other identifier columns.
However the tables do not have continuous time series i.e. some dates are missing for some of the join conditions. Furthermore I don't want "duplicate" table specific new columns to be added for a row when there is not match
I have tried COALESCE() on the dates to fill in missing dates, which is fine. However it is the subsequent joins that are causing me problems. I also can't assume that one of the tables will have rows for all the dates required.
I thought perhaps to use generate series for a date range, with empty columns (? if possible) and then join all the tables on to that?
Please see example below:
I want to join Table A and Table B on columns date, identifier_1 and identifier_2 as an outer join. However where a value is not matched I do not want new columns to be added e.g. table_b_identifier_1.
Table A
id1 and id2 are missing rows on the 03/07 and 04/07, and id1 is also missing a row for the 05/07.
Table B
id2 is missing a row on the 02/07
Desired Output:
Essentially it is a conditional join. If there is a row in both tables for identifier_1 and
It's not clear what is wrong with your attempt to use COALESCE to fill columns data, but it works well as intended in such a query
SELECT
COALESCE(a.date, b.date) AS date,
COALESCE(a.identifier_1, b.identifier_1) AS identifier_1,
COALESCE(a.identifier_2, b.identifier_2) AS identifier_2,
a.value_a,
b.value_b
FROM table_a a
FULL JOIN table_b b ON a.date = b.date
AND a.identifier_1 = b.identifier_1
AND a.identifier_2 = b.identifier_2
Please, check a demo

SQL Select - Fetching two different values from another table based on two different IDs

I have two tables
Table 1 has five columns
EmployeeID,
EmployeeCarModelID,
EmployeeCarModelName,
SpouseCarModelID,
SpouseCarModelName
Table 2 has two columns
CarModelID,
CarModelName
How would I construct a select statement which will pull through the CarModelName to both the EmployeeCarModelName and the SpouseCarModelName based on their respective IDs? I'm not sure I can use a JOIN statement to do this as we are looking at two different id columns within the same table.
You need two joins to do this. I think you want:
select t1.EmployeeId, t1.EmployeeCarModelID, t2emp.CarModelName as EmployeeCarModelName,
t1.SpouseCarModelID, t2sp.CarModelName as SpouseCarModelName
from table1 t1 left join
table2 t2emp
on t1.EmployeeCarModelID = t2emp.CarModelId left join
table2 t2sp
on t1.SpouseCarModelId = t2sp.CarModelId;

SQL join result errors

I'm trying to run this join and I'm not receiving the correct values.
My first query return like 25,000 record
SELECT count(*) from table1 as DSO,
table2 as EAR
WHERE
(UCASE(TRIM(EAR.value)) = UCASE(TRIM(DSO.value))
AND
UCASE(TRIM(EAR.value1) = UCASE(TRIM(DSO.value1))
my second Query return like 3,000,000
SELECT count(*) from table1 as DSO
left join table2 as EAR,
ON
(UCASE(TRIM(EAR.value)) = UCASE(TRIM(DSO.value))
AND
UCASE(TRIM(EAR.value1) = UCASE(TRIM(DSO.value1))
The total of records of the table 1 are like 45,000, thats what I Should recieve.
First query is an INNER JOIN and second one is a LEFT JOIN. You should expect quite different results. Also, look at the way db2400 treats NULLs with the UCASE and TRIM functions. My guess is that your left join is making some matches that you don't want.
The INNER JOIN in the first query is going to exclude any records from table1 that don't have a match in table2. That pretty quickly explains the lower count.
Either join will happily create more than one row for each record in table1 if it finds multiple matches in table2. The difference is that the LEFT JOIN will ALSO create one row for each record in table1 that doesn't have a match in table2. It sounds like you expect there to be a 1:1 match between the two tables, but that is not what you are getting.

SQL Join for cell content, not column name

I read up on SQL Join but as far as I understand it, you can only join tables which have a column name in common.
I have information in two different tables, but the column name is different in each. I need to pull information on something which is only in one of the tables, but also need information from the other. So was looking to join/merge them.
Here is what I mean..
TABLE1:
http://postimg.org/image/hnd63c2f5/
The cell content 18599 in column from_pin_id also pertains to content in another table:
TABLE2:
http://postimg.org/image/apmu26l5z/
My question is how do I merge the two table details so that it recognizes 18599 is referring to the same thing, so that I can pull content on it from other columns in TABLE2?
I've looked through the codes on W3 but cannot find anything to what I need, as mentioned above, it seems to be just for joining tables with a common column:
SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;
You can write as :
select * from table1
where from_pin_id in
(
select from_pin_id
from table1
intersect
select id
from table2
)
Intersect operator selects all elements that belong to both of the sets.
Change the table names and the columns that you select as needed.
SELECT table1.id, table1.owner_user_id, table1.from_pin_id, table2.board_id
FROM table1
JOIN table2 ON table1.from_pin_id = table2.id
GROUP BY id, owner_user_id, from_pin_id, board_id

How do I write an SQL query to identify duplicate values in a specific field?

This is the table I'm working with:
I would like to identify only the ReviewIDs that have duplicate deduction IDs for different parameters.
For example, in the image above, ReviewID 114 has two different parameter IDs, but both records have the same deduction ID.
For my purposes, this record (ReviewID 114) has an error. There should not be two or more unique parameter IDs that have the same deduction ID for a single ReviewID.
I would like write a query to identify these types of records, but my SQL skills aren't there yet. Help?
Thanks!
Update 1: I'm using TSQL (SQL Server 2008) if that helps
Update 2: The output that I'm looking for would be the same as the image above, minus any records that do not match the criteria I've described.
Cheers!
SELECT * FROM table t1 INNER JOIN (
SELECT review_id, deduction_id FROM table
GROUP BY review_id, deduction_id
HAVING COUNT(parameter_id) > 1
) t2 ON t1.review_id = t2.review_id AND t1.deduction_id = t2.deduction_id;
http://www.sqlfiddle.com/#!3/d858f/3
If it is possible to have exact duplicates and that is ok, you can modify the HAVING clause to COUNT(DISTINCT parameter_id).
Select ReviewID, deduction_ID from Table
Group By ReviewID, deduction_ID
Having count(ReviewID) > 1
http://www.sqlfiddle.com/#!3/6e113/3 has an example
If I understand the criteria: For each combination of ReviewID and deduction_id you can have only one parameter_id and you want a query that produces a result without the ReviewIDs that break those rules (rather than identifying those rows that do). This will do that:
;WITH review_errors AS (
SELECT ReviewID
FROM test
GROUP BY ReviewID,deduction_ID
HAVING COUNT(DISTINCT parameter_id) > 1
)
SELECT t.*
FROM test t
LEFT JOIN review_errors r
ON t.ReviewID = r.ReviewID
WHERE r.ReviewID IS NULL
To explain: review_errors is a common table expression (think of it as a named sub-query that doesn't clutter up the main query). It selects the ReviewIDs that break the criteria. When you left join on it, it selects all rows from the left table regardless of whether they match the right table and only the rows from the right table that match the left table. Rows that do not match will have nulls in the columns for the right-hand table. By specifying WHERE r.ReviewID IS NULL you eliminate the rows from the left hand table that match the right hand table.
SQL Fiddle