CONCAT value in ON condition of JOIN - sql

I have two tables.
Table: Geonames:
Country (2 character ISO code, e.g. SE)
AdminArea (Char code, e.g. 0330)
Table AdminAreas
AdminCode, (Combination of Coutry and AdminArea, e.g. "SE.0330")
So the ID of the AdminAreas that I want to join the tables on is a combination of columns on the first table. To join it I will need to join the two values from the Geonames table. Something like.
SELECT
geoname.geonameid, geoname.name, geoname.latitude, geoname.longitude,
geoname.country, geoname.admin1, admin_one.admin_id, admin_one.geoname_id
FROM geoname
INNER JOIN admin_one ON admin_one.admin_id = CONCAT(geoname.country, '.', geoname.admin1)
WHERE country='SE' LIMIT 10
Unfortunately, this is not working. It does not seem like i can CONCAT or do string_agg() on a JOIN. How do I get this JOIN working?

Your code is fine. Perhaps one issue is that you have spaces or some other character. I would recommend investigating this using:
SELECT gn.geonameid, gn.name, gn.latitude, gn.longitude,
gn.country, gn.admin1, ao.admin_id, ao.geoname_id
FROM geoname gn LEFT JOIN
admin_one ao
ON ao.admin_id = CONCAT(TRIM(gn.country), '.', TRIM(gn.admin1))
WHERE gn.country = 'SE'
LIMIT 10;
This will return even unmatched results (because of the LEFT JOIN). That might help you investigate the issue.

Related

ACCESS SQL - Joining 2 tables on Datetime values

I have an issue joining 2 tables with datetime values in Access.
I tried to join the tables by simply setting
LEFT JOIN Table1.Datetime=Table2.Datetime
However, the output of my query is really off.
I then tried to join by splitting the dates:
LEFT JOIN YEAR(Table1.Datetime)=YEAR(Table2.Datetime)
AND MONTH(Table1.Datetime)=MONTH(Table2.Datetime)
AND DAY(Table1.Datetime)=DAY(Table2.Datetime)
AND HOUR(Table1.Datetime)=HOUR(Table2.Datetime)
Running it this way, the query seems stucked and I don't ever get any results.
I then tied joining both table on a condition like:
LEFT JOIN Table1.Datetime>=Table2.Datetime
AND Table1.Datetime<Table2.Datetime + 1/24
I'm running out of ideas for my join to effectively work, any help would be much appreciated !
DateTime is based on Double, and you can't just check such values for equality because of potential floating point errors.
Try something like this:
LEFT JOIN Abs(Table1.Datetime-Table2.Datetime) < #00:00:01#
or:
LEFT JOIN DateDiff("s", Table1.Datetime, Table2.Datetime) = 0
or:
LEFT JOIN Format(Table1.Datetime, yyyymmddhhnnss") = Format(Table2.Datetime, yyyymmddhhnnss")
These may be too slow, however. If so, join two simple select queries, one for each table, having:
Format(Table1.Datetime, "yyyymmddhhnnss") As TextTime - and
Format(Table2.Datetime, "yyyymmddhhnnss") As TextTime
and then join on
query1.TextTime = query2.TextTime

conditional IIF in a JOIN

I have the next data base:
Table Bill:
Table Bill_Details:
And Table Type:
I want a query to show this result:
The query as far goes like this:
SELECT
Bill.Id_Bill,
Type.Id_Type,
Type.Info,
Bill_Details.Deb,
Bill_Details.Cre,
Bill.NIT,
Bill.Date2,
Bill.Comt
FROM Type
RIGHT JOIN (Bill INNER JOIN Bill_Details
ON Bill.Id_Bill = Bill_Details.Id_Bill)
ON Type.Id_Type = Bill_Details.Id_Type
ORDER BY Bill.Id_Bill, Type.Id_Type;
With this result:
I'm not sure how to deal or how to include this:
Type.600,
Type."TOTAL",
IIF(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre) >= 0, ABS(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre)), "" ),
IIF(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre) <= 0, ABS(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre)), "" )
The previous code is the responsable of include new data in some fields, since all of the other fields will carry the same data of the upper register. I'll apreciate some sugestions to acomplish this.
Here is a revised version of the UNION which you removed from the question. The original query was a good start, but you just did not provide sufficient details about the error or problem you were experiencing. My comments were not meant to have you remove the problem query, only that you needed to provide more details about the error or problem. In the future if you have a UNION, make sure the each query of the UNION works separately. Then you could debug problems easier, one step at a time.
Problems which I corrected in the second query of the UNION:
Removed reference to table [Type] in the query, since it was not part of the FROM clause. Instead, I replaced it with a literal value.
Fixed FROM clause to join both [Bill] and [Bill_Details] tables. You had fields from both tables, so why would you not join on them just like in the first query of the UNION?
Grouped on all fields from table [Bill] referenced in the SELECT clause. You must either group on all fields, or include them in aggregate expressions like Sum() or First(), etc.
Replaced empty strings with Nulls for the False cases on Iif() statements.
SELECT
Bill.Id_Bill, Type.Id_Type, Type.Info,
Bill_Details.Deb,
Bill_Details.Cre,
Bill.NIT, Bill.Date2, Bill.Comt
FROM
Type RIGHT JOIN (Bill INNER JOIN Bill_Details
ON Bill.Id_Bill = Bill_Details.Id_Bill)
ON Type.Id_Type = Bill_Details.Id_Type;
UNION
SELECT
Bill.Id_Bill, 600 As Id_Type, "TOTAL" As Info,
IIF(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre) >= 0, ABS(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre)), Null ) As Deb,
IIF(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre) <= 0, ABS(SUM(Bill_Details.Deb) - Sum(Bill_Details.Cre)), Null ) As Cre,
Bill.NIT, Bill.Date2, Bill.Comt
FROM Bill INNER JOIN Bill_Details
ON Bill.Id_Bill = Bill_Details.Id_Bill
GROUP BY Bill.Id_Bill, Bill.NIT, Bill.Date2, Bill.Comt;

Merge / Join SQL Select Queries

I am struggling with combining the below Select Statments, I know I could cheat and add some fake columns in and then use Union, but I want to do this correctly.
Once I have them joined, I will be putting the Statment in to a XML file for use with Word and CRM4.
SELECT BILLTO_NAME,
BILLTO_LINE1,
BILLTO_LINE2,
BILLTO_LINE3,
BILLTO_CITY,
BILLTO_COUNTRY,
BILLTO_POSTALCODE,
ORDERNUMBER,
REQUESTDELIVERYBY,
MODIFIEDON,
SHIPTO_NAME,
SHIPTO_LINE1,
SHIPTO_LINE2,
SHIPTO_LINE3,
SHIPTO_CITY,
SHIPTO_STATEORPROVINCE,
SHIPTO_COUNTRY,
SHIPTO_POSTALCODE,
CREATEDBY
FROM SALESORDERBASE
SELECT QUANTITY,
DESCRIPTION
FROM SALESORDERDETAILBASE
SELECT NEW_ORDERNOTES,
NEW_NOTES
FROM SALESORDEREXTENSIONBASE
They all have the common column of SalesOrderID, which I need to add in somewhere as well.
You can use a LEFT JOIN on the tables:
SELECT ob.SalesOrderID
ob.BILLTO_NAME,
ob.BILLTO_LINE1,
ob.BILLTO_LINE2,
ob.BILLTO_LINE3,
ob.BILLTO_CITY,
ob.BILLTO_COUNTRY,
ob.BILLTO_POSTALCODE,
ob.ORDERNUMBER,
ob.REQUESTDELIVERYBY,
ob.MODIFIEDON,
ob.SHIPTO_NAME,
ob.SHIPTO_LINE1,
ob.SHIPTO_LINE2,
ob.SHIPTO_LINE3,
ob.SHIPTO_CITY,
ob.SHIPTO_STATEORPROVINCE,
ob.SHIPTO_COUNTRY,
ob.SHIPTO_POSTALCODE,
ob.CREATEDBY,
od.QUANTITY,
od.DESCRIPTION,
oe.NEW_ORDERNOTES,
oe.NEW_NOTES
FROM SALESORDERBASE ob
LEFT JOIN SALESORDERDETAILBASE od
on ob.SalesOrderID = od.SalesOrderID
LEFT JOIN SALESORDEREXTENSIONBASE oe
on ob.SalesOrderID = oe.SalesOrderID
Assuming the column that identifies the relationship is called id on all three tables, you can do this:
SELECT sob.BILLTO_NAME,
sob.BILLTO_LINE1,
sob.BILLTO_LINE2,
sob.BILLTO_LINE3,
sob.BILLTO_CITY,
sob.BILLTO_COUNTRY,
sob.BILLTO_POSTALCODE,
sob.ORDERNUMBER,
sob.REQUESTDELIVERYBY,
sob.MODIFIEDON,
sob.SHIPTO_NAME,
sob.SHIPTO_LINE1,
sob.SHIPTO_LINE2,
sob.SHIPTO_LINE3,
sob.SHIPTO_CITY,
sob.SHIPTO_STATEORPROVINCE,
sob.SHIPTO_COUNTRY,
sob.SHIPTO_POSTALCODE,
sob.CREATEDBY,
sodb.QUANTITY,
sodb.DESCRIPTION,
soeb.NEW_ORDERNOTES,
soeb.NEW_NOTES
From SalesOrderBase sob
JOIN SalesOrderDetailBase sodb
ON sob.id = sodb.SalesOrderID
JOIN SalesOrderExtensionBase soeb
ON sob.id = soeb.SalesOrderID
You can think of JOINing as slamming together rows side-by-side, whereas UNIONing is slamming together rows one on top of the other. UNIONS require that the columns be the same and JOINs require that there is a relationship of some kind between each row.
EDIT - The OP provided more details

Access Left Join not working properly

In access I wrote this query:
Select
I.sysid, I.MemberNumber, I.Date, I.Distributer,
F.MemberNumber as FMember, F.Date as FDate, I.Distributer as FDistributer
From Initial as I
Left Join Final as F ON
I.MemberNumber=F.MemberNumber and
I.Distributer=F.Distributer and
I.Date>=F.Date-14 and
I.Date<=F.Date+14;
But the left join is not behavior properly. There are fewer rows in this table then there are in Initial... but it should be keeping ALL rows from initial, because I am using a left join, right? I have found several rows in initial (like sysid=7, which is Initial's key) that just isn't coming into this table.
It may have to do with your AND logic. Add some ( ) parenthesis to this to include it all like so:
Select
I.sysid, I.MemberNumber, I.Date, I.Distributer,
F.MemberNumber as FMember, F.Date as FDate, I.Distributer as FDistributer
From Initial as I
Left Join Final as F ON
(I.MemberNumber=F.MemberNumber and
I.Distributer=F.Distributer and
(I.Date>=F.Date-14) and
(I.Date<=F.Date+14));
Also I think there is a dateadd function, I'd use that instead of + / -.
If you're in the Query Designer, make sure all the filters are cleared. I've built your tables and sql and can't reproduce your error.
SELECT I.sysid
, I.MemberNumber
, I.Dated
, I.Distributer
, F.MemberNumber
, F.Dated AS FDated
, F.Distributer AS FDistributer
FROM Initial AS I
LEFT JOIN Final AS F
ON I.Distributer = F.Distributer
AND I.MemberNumber = F.MemberNumber
AND I.Dated>=F.Dated-14
AND I.Dated<=F.Dated+14;
Try adding additional fields to the original table and using update queries to add extra columns. This way you can be sure you won't drop any columns.

Why do I have to use DISTINCT for this to work?

here's my problem: I have an SQL query that makes 4 calls to a lookup table to return their values from a list of combinations in another table. I finally got this working, and for some reason, when I run the query without DISTINCT, I get a ton of data back, so I'm guessing that I'm either missing something or not doing this correctly. It would be really great if this would not only work, but also return the list alphabetically by the first colour name.
I'm putting my SQL here I hope I've explained this well enough:
SELECT DISTINCT
colour1.ColourID AS colour1_ColourID,
colour1.ColourName AS colour1_ColourName,
colour1.ColourHex AS colour1_ColourHex,
colour1.ManufacturerColourID AS colour1_ManufacturerColourID,
colour2.ColourID AS colour2_ColourID,
colour2.ColourName AS colour2_ColourName,
colour2.ColourHex AS colour2_ColourHex,
colour2.QEColourID2 AS colour2_QEColourID2,
colour3.ColourID AS colour3_ColourID,
colour3.ColourName AS colour3_ColourName,
colour3.ColourHex AS colour3_ColourHex,
colour3.QEColourID3 AS colour3_QEColourID3,
colour4.ColourID AS colour4_ColourID,
colour4.ColourName AS colour4_ColourName,
colour4.ColourHex AS colour4_ColourHex,
colour4.QEColourID4 AS colour4_QEColourID4,
Combinations.ID,
Combinations.ManufacturerColourID AS Combinations_ManufacturerColourID,
Combinations.QEColourID2 AS Combinations_QEColourID2,
Combinations.QEColourID3 AS Combinations_QEColourID3,
Combinations.QEColourID4 AS Combinations_QEColourID4,
Combinations.ColourSupplierID,
ColourSuppliers.ColourSupplier
FROM
ColourSuppliers INNER JOIN
(
colour4 INNER JOIN
(
colour3 INNER JOIN
(
colour2 INNER JOIN
(
colour1 INNER JOIN Combinations ON
colour1.ColourID=Combinations.ManufacturerColourID
) ON colour2.ColourID=Combinations.QEColourID2
) ON colour3.ColourID=Combinations.QEColourID3
) ON colour4.ColourID=Combinations.QEColourID4
) ON ColourSuppliers.ColourSupplierID=Combinations.ColourSupplierID
WHERE Combinations.ColourSupplierID = ?
Thanks
Steph
It looks as though you've probably got multiple records for each set of four colour combinations in the Combinations table - posting the structure of the table might help us to work it out.
Adding the clause order by colour1.ColourName to the end of the query should sort it alphabetically by the first colour name.
My guess (and it is a guess because your SQL query is very wide!) is that you're getting the cartesian product.