Why does this SQL Query not work for me? - mysql

I have some problems with an (My)SQL query. In my DB I have two tables. One is called kfz_typen, the other kfz_temp2. I need to get all entries of the kfz_temp2 table, which ktyp (just an integer field) is not in the kfz_typen table.
SELECT * FROM kfz_temp2
WHERE kfz_temp2.KType NOT IN (SELECT DISTINCT kfz_typen.ktyp FROM kfz_typen)
In my opinion this query above should exactly do, what I want. But it doesn't! I just get an empty result back from my MySQL Server.
Without the "NOT" in the Query, I get the entries that are in both tables, so the matching does work.
So what's wrong with the Query above?

Would this work?
SELECT t2.* FROM kfz_temp2 t2
LEFT JOIN kfz_typen tn ON t2.KType = tn.ktyp
WHERE tn.ktyp IS NULL
You may need to group the result.
I'm unsure why the first query doesn't work, but I believe this does the same thing.

remove distinct then i hope it is helpful to you.

Related

Anyone know why the DISTINCT keyword in MYSQL isnt working here?

I understand that they aren't exactly duplicate rows, but how do I specify the DISTINCT command to only check for the first column.
Thanks in advance
You need
FROM Employees JOIN Departments
ON Employees.dep_id = Departments.dep_id
Without an ON clause a JOIN is a Cartesian join, yielding every possible combination of rows in the two tables.
DISTINCT is not useful for solving this problem.
DISTINCT works on the entire row returned, not a single attribute.
(Frank, William, Sales)
...is distinct from...
(Frank, William, IT)
...even if some of the attributes are the same.
PS- please include quoted code and results instead of a link.

Join Performances When Searching For NULL Value

I need to find a value that exists in LoyaltyTransactionBasketItemStores table but not in DimProductConsolidate table. I need the item code and its corresponding company. This is my query
SELECT
A.ProductReference, A.CompanyCode
FROM
(SELECT ProductReference, CompanyCode FROM dwhdb.LoyaltyTransactionsBasketItemsStores GROUP BY ProductReference) A
LEFT JOIN
(SELECT LoyaltyVariantArticleCode FROM dwhdb.DimProductConsolidate) B ON B.LoyaltyVariantArticleCode = A.ProductReference
WHERE
B.LoyaltyVariantArticleCode IS NULL
It is a pretty straight forward query. But when I run it, it's taking 1 hour and still not finish. Then I use EXPLAIN and this is the result
But when I remove the CompanyCode from my query, its performance is increasing a lot. This is the EXPLAIN result
I want to know why is this happening and is there any way to get ProductReference and its company with a lot more better performance?
Your current query is rife with syntax and structural errors. I would use exists logic here:
SELECT a.ProductReference, a.CompanyCode
FROM dwhdb.LoyaltyTransactionsBasketItemsStores a
WHERE NOT EXISTS (SELECT 1 FROM dwhdb.DimProductConsolidate b
WHERE b.LoyaltyVariantArticleCode = a.ProductReference);
Your current query is doing a GROUP BY in the first subquery, but you never select aggregates, but rather other non aggregate columns. On most other databases, and even on MySQL in strict mode, this syntax is not allowed. Also, there is no need to have 2 subqueries here. Rather, just select from the basket table and then assert that matching records do not exist in the other table.

MySQL Select from 1 Table, Insert into Another using Where across different databases

I have a select shown below that brings back the correct count per "sender_userid".
I want to insert this into a table in another database where there is a matching column "userid".
I'm not sure how to get the WHERE clause to work when used across database.
I've tried database.table.column but this appears wrong.
Is this possible? thx
WHERE statements must come before ORDER BY and GROUP BY statements. Also you should use the ON operator. Try this:
INSERT INTO dating_users.statistics (messages_sent)
SELECT COUNT(pid) FROM dating_messages.messages M
JOIN dating_users.statistics S
ON (S.userid = M.sender_userid)
GROUP BY sender_userid ORDER BY sender_userid ASC;
Edit: sorry I didn't realize that you were missing your actual JOIN statement. Just because you are INSERTing into a table doesn't make any data accessible from that table. You still need to JOIN to it.

mysql query join doesnt work but sql "where" does

i am trying to run a join query on mysql i am using following query:
SELECT `Reservation`.`id`
FROM `reservations` AS `Reservation`
LEFT JOIN rates ON Reservation.postal_code=rates.postal_code
this gives my results only for "Reservation" table, and no results for the "rates" table at all, but the following query works fine
SELECT `Reservation`.`id`, rates.id
FROM `reservations` AS `Reservation`, rates
WHERE Reservation.postal_code = rates.postal_code
i am unsure what am i doing wrong, can someone please help?
edit
I was using cakephp and this is just a modified version of a query generated by cakephp and it didnt specify the fields in "select" case so i thought it isn't needed.
You have to include them in the SELECT
SELECT `Reservation`.`id`, rates.*
FROM `reservations` AS `Reservation`
LEFT JOIN rates ON Reservation.postal_code=rates.postal_code
In your second query you have rates.id, that is including it.
NOTE: Don't use the kind of join from the second query you showed us. That's a cross join (theta join) and will make your query go really slow. Always use JOINS.
The first query returns only a single column, id, from reservations. Are you expecting to see data from rates as well? You must mention those columns after the keyword SELECT.
The second query includes the column id from rates.
If you modify the queries so they return the same list of columns they will produce similar (but not identical results). They will still differ in that the second query may return fewer rows — it will not include reservations with 0 corresponding rates (because it uses an INNER JOIN).
The first query isn't selecting from the Rates table. Try this:
SELECT `Reservation`.`id`, `rates`.`id`
FROM `reservations` AS `Reservation`
LEFT JOIN rates ON Reservation.postal_code=rates.postal_code

MySQL: Include COUNT of SELECT Query Results as a Column (Without Grouping)

I have a simple report sending framework that basically does the following things:
It performs a SELECT query, it makes some text-formatted tables based on the results, it sends an e-mail, and it performs an UPDATE query.
This system is a generalization of an older one, in which all of the operations were hard coded. However, in pushing all of the logic of what I'd like to do into the SELECT query, I've run across a problem.
Before, I could get most of the information for my text tables by saying:
SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT';
Then, when I needed an extra number for the e-mail, also do:
SELECT COUNT(*) FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
Now, I no longer have the luxury of multiple SELECT queries. What I'd like to do is something like:
SELECT Tabl.Name, Tabl.Address, COUNT(Results.UID) AS Totals
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
AND Results.TimeLogged='Noon'
WHERE Status='URGENT';
This, at least in my head, says to get a total count of all the rows that were SELECTed and also have some conditional.
In reality, though, this gives me the "1140 - Mixing of GROUP columns with no GROUP columns illegal if no GROUP BY" error. The problem is, I don't want to GROUP BY. I want this COUNT to redundantly repeat the number of results that SELECT found whose TimeLogged='Noon'. Or I want to remove the AND clause and include, as a column in the result of the SELECT statement, the number of results that that SELECT statement found.
GROUP BY is not the answer, because that causes it to get the COUNT of only the rows who have the same value in some column. And COUNT might not even be the way to go about this, although it's what comes to mind. FOUND_ROWS() won't do the trick, since it needs to be part of a secondary query, and I only get one (plus there's no LIMIT involved), and ROW_COUNT() doesn't seem to work since it's a SELECT statement.
I may be approaching it from the wrong angle entirely. But what I want to do is get COUNT-type information about the results of a SELECT query, as well as all the other information that the SELECT query returned, in one single query.
=== Here's what I've got so far ===
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
This does use sub-SELECTs, which I was initially hoping to avoid, but now realize that hope may have been foolish. Plus it seems like the COUNTing SELECT sub-queries will be less costly than the main query since the COUNT conditionals are all on one table, but the real SELECT I'm working with has to join on multiple different tables for derived information.
The key realizations are that I can GROUP BY NULL, which will return a single result so that COUNT(*) will actually catch everything, and that I can force a correlation to this column by just faking a Bonus column with 0 on both tables.
It looks like this is the solution I will be using, but I can't actually accept it as an answer until tomorrow. Thanks for all the help.
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
I figured this out thanks to ideas generated by multiple answers, although it's not actually the direct result of any one. Why this does what I need has been explained in the edit of the original post, but I wanted to be able to resolve the question with the proper answer in case anyone else wants to perform this silly kind of operation. Thanks to all who helped.
You could probably do a union instead. You'd have to add a column to the original query and select 0 in it, then UNION that with your second query, which returns a single column. To do that, the second query must also select empty fields to match the first.
SELECT Cnt = 0, Name, Address FROM Databas.Tabl WHERE Status='URGENT'
UNION ALL
SELECT COUNT(*) as Cnt, Name='', Address='' FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
It's a bit of a hack, but what you're trying to do isn't ideal...
Does this do what you need?
SELECT Tabl.Name ,
Tabl.Address ,
COUNT(Results.UID) AS GrandTotal,
COUNT(CASE WHEN Results.TimeLogged='Noon' THEN 1 END) AS NoonTotal
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
WHERE Status ='URGENT'
GROUP BY Tabl.Name,
Tabl.Address
WITH ROLLUP;
The API you're using to access the database should be able to report to you how many rows were returned - say, if you're running perl, you could do something like this:
my $sth = $dbh->prepare("SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'");
my $rv = $sth->execute();
my $rows = $sth->rows;
Grouping by Tabl.id i dont believe would mess up the results. Give it a try and see if thats what you want.