Ambiguous JOIN variable - in initial FROM... really? - mysql

EDIT OK so the main problem here was initial column1 FROM table1 with the join. Even that column1 has to be fully defined as table1.column1 even tho it is next to the FROM which seems at best odd to me. But I guess this is a newb error and I hope other newbs will find this useful.
//========================================================================
Have used simple joins before without problems. I thought the table.column format was unambiguous.
Warning is:
Integrity constraint violation: 1052 Column 'transmissionProgramID'
in field list is ambiguous'
The SQL is:
SELECT transmissionProgramID FROM transmissionProgramOwner
JOIN transmissionProgram on transmissionProgram.transmissionProgramID
= transmissionProgramOwner.transmissionProgramID WHERE
ownerType = '$ownerType' AND ownerID = '$ownerID' ORDER BY startDate
The two table transmissionProgramOwner and transmissionProgram both have fields called transmissionProgramID. I just cannot see how the table.column leaves anything ambiguous.
Sure it is something simple but I cannot see it. And I apologize for the long variable names but helps me keep things clear.
Additional info: Both transmissionProgramID are set to unique in both tables. I have tried every flaovor of JOIN but I think a simple join is allowed which just returns all records that match... In any case have tried every type of join just to make sure.

Friend try this
SELECT t1.transmissionProgramID FROM transmissionProgramOwner t1
JOIN transmissionProgram t2 on t2.transmissionProgramID
= t1.transmissionProgramID WHERE
t1.ownerType = '$ownerType' AND t1.ownerID = '$ownerID' ORDER BY t1.startDate;

change to
SELECT transmissionProgram.transmissionProgramID FROM
transmissionProgramOwner JOIN transmissionProgram on
'transmissionProgram.transmissionProgramID'
= 'transmissionProgramOwner.transmissionProgramID' WHERE ownerType = '$ownerType' AND ownerID = '$ownerID' ORDER BY startDate

Related

MAX(Date) is giving empty result

I have a table with exchange rate like below
And I am using the maxofdate to pick all these values based on currency code. But the query is giving blank.
Select USDAMOUNT * dbo.EXCHANGERATEAMT
from dbo.Amount_monthly
Left Join dbo.EXCHANGERATE on dbo.Amount_monthly.Currencycode=dbo.EXCHANGERATE.fromcurrencycode
WHERE ValidToDateTime = (Select MAX(ValidToDateTime) from dbo.EXCHANGERATE)
AND dbo.EXCHANGERATE.EXCHANGERATETYPECODE = 'DAY'
Using this statement
CONVERT(DATE,ValidToDateTime) = CONVERT(DATE,GETDATE()-1)
instead of subquery is giving me expected result.
Can someone correct this.
thanks in advance.
If I understand correctly, you need two things. First, the condition for the max() needs to match the condition in the outer query. Second, if you really want a left join, then conditions on the second table need to go in the on clause.
The resulting query looks like:
Select . . .
from dbo.Amount_monthly am Left Join
dbo.EXCHANGERATE er
on am.Currencycode = er.fromcurrencycode and
er.ValidToDateTime = (Select max(er2.ValidToDateTime)
from dbo.EXCHANGERATE er2
where er2.EXCHANGERATETYPECODE = 'DAY'
) and
er.EXCHANGERATETYPECODE = 'DAY';
I would write this using window functions, but that is a separate issue.
Try removing WHERE clause for ValidToDateTime and include it in the JOIN as AND condition
SELECT USDAMOUNT * dbo.EXCHANGERATEAMT
FROM dbo.Amount_monthly
LEFT JOIN dbo.EXCHANGERATE
ON dbo.Amount_monthly.Currencycode = dbo.EXCHANGERATE.fromcurrencycode
AND ValidToDateTime = (SELECT MAX(ValidToDateTime) --remove WHERE clause
FROM dbo.EXCHANGERATE)
AND dbo.EXCHANGERATE.EXCHANGERATETYPECODE = 'DAY';
I cleaned up your query a bit: as the other folks mentioned you needed to close the parentheses around the MAX(Date) sub-query, and if you reference a LEFT JOINed table in the WHERE clause, it behaves like an INNER JOIN, so I changed to in INNER. You also had "dbo" sprinkled in as a field prefix, but that (the namespace) only prefixes a database, not a field. I added the IS NOT NULL check just to avoid SQL giving the "null values were eliminated" SQL warning. I used the aliases "am" for the first table and "er" for the 2nd, which makes it more readable:
SELECT am.USDAMOUNT * er.EXCHANGERATEAMT
FROM dbo.Amount_monthly am
JOIN dbo.EXCHANGERATE er
ON am.Currencycode = er.fromcurrencycode
WHERE er.ValidToDateTime = (SELECT MAX(ValidToDateTime) FROM dbo.EXCHANGERATE WHERE ValidToDateTime IS NOT NULL)
AND er.EXCHANGERATETYPECODE = 'DAY'
If you're paranoid like I am, you might also want to make sure the exchange rate is not zero to avoid a divide-by-zero error.

DELETE FROM table WHERE condition is met in other table

I have this SQL query that has been working great. I would like to have something similar that would delete a line from PRC_FIX when the column DESCR in IM_ITEM begins with Clearance instead of where ITEM_VEND_NO = 'GAMES WORK'.
DELETE `PRC_FIX` FROM `PRC_FIX`
INNER JOIN `IM_ITEM` ON `IM_ITEM`.`ITEM_NO` = `PRC_FIX`.`ITEM_NO`
AND `IM_ITEM`.`ITEM_VEND_NO` = 'GAMES WORK'
Thanks for your help.
Edit: This was marked as a possible duplicate. I don't know that looking at the suggested duplicate would have helped me because I wouldn't have known how to implement it in this scenario involving 2 tables, but I'm willing to admit that might be my fault due to me being new to SQL.
You can use
DELETE PRC_FIX
FROM PRC_FIX
INNER JOIN IM_ITEM
ON IM_ITEM.ITEM_NO = PRC_FIX.ITEM_NO
WHERE UPPER(IM_ITEM.DESCR) LIKE 'CLEARANCE%';
You need to use the wildcard %.
in order to match with this string with different string which begins with "Clearance" you need to use "Clearance%".
Look here: SQL like search string starts with
You're fixed code:
DELETE `PRC_FIX` FROM `PRC_FIX`
INNER JOIN `IM_ITEM` ON `IM_ITEM`.`ITEM_NO` = `PRC_FIX`.`ITEM_NO`
AND IM_ITEM.DESCR LIKE 'Clearance%'
DETELE FROM PRC_FIX WHERE ITEM_NO IN (SELECT ITEM_NO FROM IM_ITEM WHERE ITEM_VEND_NO` = 'GAMES WORK')

Please help: Multi-part identifier could not be bound

I know there are quite a few posts regarding this topic, but I'm really stumped as to why my code isn't working. I simply have two tables and am trying to update a value in one table with information from the other based on a where statement. I have pretty much used this same code in other instance to do this without any issue, so I'm not sure why I'm getting an error here in this case. If anyone could offer up any assistance, I'd greatly appreciate it.
Code:
update [DB].[dbo].[table1]
set [DB].[dbo].[table1].[variable_name] = [DB].[dbo].[table2].[variable_name]
where ([DB].[dbo].[table1].[Year] = [DB].[dbo].[table2].[Year] and
[DB].[dbo].[table1].[Id] = [DB].[dbo].[table2].[Id]);
Variable_Name is text in both tables and Year/Id are both Int.
You need to join table2 in the update statement.
UPDATE t1
SET [table1].[variabe_name] = [table2].[variable_name]
FROM [table1] t1
INNER JOIN [table2]
ON [table1].[variable_name] = [table2].[variable_name]
WHERE ([table1].[Year] = [table2].[Year] AND [table1].[Id] = [table2].[Id]);

MySQL: Subquery returns more than 1 row

I know this has been asked plenty times before, but I cant find an answer that is close to mine.
I have the following query:
SELECT c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName, c.cases_timestamp, o.organisation_name
FROM db_cases c, db_custinfo ci, db_organisation o
WHERE c.userInfo_ID = ci.userinfo_ID AND c.cases_status = '2'
AND organisation_name = (
SELECT organisation_name
FROM db_sites s, db_cases c
WHERE organisation_ID = '111'
)
AND s.sites_site_ID = c.sites_site_ID)
What I am trying to do is is get the cases, where the sites_site_ID which is defined in the cases, also appears in the db_sites sites table alongside its organisation_ID which I want to filter by as defined by "organisation_ID = '111'" but I am getting the response from MySQL as stated in the question.
I hope this makes sense, and I would appreciate any help on this one.
Thanks.
As the error states your subquery returns more then one row which it cannot do in this situation. If this is not expect results you really should investigate why this occurs. But if you know this will happen and want only the first result use LIMIT 1 to limit the results to one row.
SELECT organisation_name
FROM db_sites s, db_cases c
WHERE organisation_ID = '111'
LIMIT 1
Well the problem is, obviously, that your subquery returns more than one row which is invalid when using it as a scalar subquery such as with the = operator in the WHERE clause.
Instead you could do an inner join on the subquery which would filter your results to only rows that matched the ON clause. This will get you all rows that match, even if there is more than one returned in the subquery.
UPDATE:
You're likely getting more than one row from your subquery because you're doing a cross join on the db_sites and db_cases table. You're using the old-style join syntax and then not qualifying any predicate to join the tables on in the WHERE clause. Using this old style of joining tables is not recommended for this very reason. It would be better if you explicitly stated what kind of join it was and how the tables should be joined.
Good pages on joins:
http://dev.mysql.com/doc/refman/5.0/en/join.html (for the right syntax)
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html (for the differences between the types of joins)
I was battling this for an hour, and overcomplicated it completely. Sometimes a quick break and writing it out on an online forum can solve it for you ;)
Here is the query as it should be.
SELECT c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName, c.cases_timestamp, c.sites_site_ID
FROM db_cases c, db_custinfo ci, db_sites s
WHERE c.userInfo_ID = ci.userinfo_ID AND c.cases_status = '2' AND (s.organisation_ID = '111' AND s.sites_site_ID = c.sites_site_ID)
Let me re-write what you have post:
SELECT
c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName,
c.cases_timestamp, c.sites_site_ID
FROM
db_cases c
JOIN
db_custinfo ci ON c.userInfo_ID = ci.userinfo_ID and c.cases_status = '2'
JOIN
db_sites s ON s.sites_site_ID = c.sites_site_ID and s.organization_ID = 111

Update Value in Table from another table

I realized that i was using a varchar attribute as a index/key in a query, and that is killing my query performance. I am trying to look in my precienct table and get the integer ID, and then update my record in the household table with the new int FK, placed in a new column. this is the sql i have written thus far. but i am getting a
Error 1093 You can't specify target table 'voterfile_household' for update in FROM clause, and i am not sure how to fix it.
UPDATE voterfile_household
SET
PrecID = (SELECT voterfile_precienct.ID
FROM voterfile_precienct INNER JOIN voterfile_household
WHERE voterfile_precienct.PREC_ID = voterfile_household.Precnum);
Try:
update voterfile_household h, voterfile_precienct p
set h.PrecID = p.ID
where p.PREC_ID = h.Precnum
Take a look at update reference here.
Similarly, you can use inner join syntax as well.
update voterfile_household h inner join voterfile_precienct p on (h.Precnum = p.PREC_id)
set h.PrecID = p.ID
What if the subquery returns more than one result? That's why it doesn't work.
On SQL Server you can get this type of thing to work if the subquery does "SELECT TOP 1 ...", not sure if mysql will also accept it if you add a "limit 1" to the subquery.
I also think this is pretty much a duplicate of this question ("Can I have an inner SELECT inside of an SQL UPDATE?") from earlier today.
Firstly, your index on a varchar isn't always a bad thing, if it is not a key you can shrink how much of the field you index to only index say the first 10 chars or so.
Secondly, it won't let you do this as if it is a set that is returned it could break.