When I use Distinct function in mysql query then I can get only one column from the table. This is example query that I am using:
SELECT DISTINCT (subcategory.title), common_cat. * FROM `subcategory`
LEFT JOIN common_cat ON ( subcategory.title = common_cat.ctitle )
It returns records as below :
title mid wid ctitle
Tops 17 5 Tops
Dresses NULL NULL NULL
Pants/Shorts 18 6 Pants/Shorts
Skirts NULL NULL NULL
Swimwear 24 8 Swimwear
Outerwear 21 9 Outerwear
In above data "Title" field coming from subcategory table.Now I also want to get id column
from subcategory table. How I can get this.
DISTINCT works by getting all the data of the columns you mentioned in a table row and then filtering out the duplicate rows and showing the unique rows with same values in ALL columns.
As such you can simply add the column subcategory.id to the column list and it will work.
SELECT DISTINCT subcategory.title, subcategory.id, common_cat.* FROM `subcategory`
JOIN common_cat ON ( subcategory.title = common_cat.ctitle )
Please note, in a distinct command it is not recommended to use * to pickup all columns as the more the number of columns in the query the more the load on the database server and hence a slower output. You may want to mention only the column names required in the distinct list and remove the common_cat.* from the query.
Related
I went through similar questions here, but no solution given there works for me.
The idea is that I need to move data from old_database's OldDoc to new_database's NewDoc. The majority of the columns match, but there are two exceptions.
Namely, USER_ID column needs to be filled with an ID extracted from new_database's User table. What ID should be given to a record is decided by comparing old_database's OldDoc's operator column (it contains just the name of the user) to a name within new_database's User table which contains names and IDs.
So if old_database's OldDoc's operator column contains a row 'Nezuko-chan' and new_database's User table has Name column saying 'Nezuko-chan' and ID column saying '666', then new_database's NewDoc's USER_ID column should be given '666' here.
Basically the same logic applies to LOCATION_ID -> there's a Location table in new_database with Name and ID and, by comparing old_database's OldDoc's lokalizacja column (with just a name) to new_database's Location's Name column, I want to extract new_database' Location's ID for that name.
Below code...
INSERT INTO new_database.NewDoc (ID, NR_DOC, NR_HANDLE, DOC_DATE, PLANNING_RELEASE, QUANTITY, CASES, VOLUME, ZAPIS, USER_ID, LOCATION_ID, TYPE_ID)
SELECT
ol.id,
ol.nrWZ,
ol.nrHandle,
ol.dataWZ,
ol.planowaneWydanie,
ol.qty,
ol.cart,
ol.volume,
ol.Zapis,
(SELECT u.ID FROM new_database.User u WHERE u.NAME = ol.operator),
(SELECT loc.ID FROM new_database.Location loc WHERE loc.NAME = ol.lokalizacja),
1
FROM old_database.OldDoc ol
... results in this festival of errors:
Column 'USER_ID' cannot be null
Column 'LOCATION_ID' cannot be null
Subquery returns more than 1 row
Column 'USER_ID' cannot be null
Column 'LOCATION_ID' cannot be null
Subquery returns more than 1 row
Column 'USER_ID' cannot be null
Column 'LOCATION_ID' cannot be null
Subquery returns more than 1 row
Column 'USER_ID' cannot be null
Column 'LOCATION_ID' cannot be null
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.id,
ol.nrWZ,
ol.nrHandle,
ol.dataWZ,
ol.planowaneWydanie,
ol.qty,
...' at line 3
I also tried replacing the syntax of my nested SELECTs with the below...
(SELECT u.ID FROM new_database.User u, old_database.OldDoc omg WHERE u.NAME = omg.operator),
(SELECT loc.ID FROM new_database.Location loc, old_database.OldDoc omg WHERE loc.NAME = omg.lokalizacja)
... which changes nothing.
This needs to be a mistake on my part as none of the columns I am trying to reach for is empty. Data is everywhere (checked by independent SELECTs).
I suppose the problem lies with my nested SELECTs which return "lists of results" instead of a single result for every row. Again, I checked similar questions before and can't find answers there so I must be making a very... individual kind of a mistake.
Thank you in advance for your time.
Kind Regards,
Bartek
Use INSERT .. SELECT with proper joining:
INSERT INTO new_database.NewDoc (
ID, NR_DOC, NR_HANDLE, DOC_DATE,
PLANNING_RELEASE, QUANTITY, CASES, VOLUME,
ZAPIS, USER_ID, LOCATION_ID, TYPE_ID
)
SELECT ol.id, ol.nrWZ, ol.nrHandle, ol.dataWZ,
ol.planowaneWydanie, ol.qty, ol.cart, ol.volume,
ol.Zapis, u.ID, loc.ID, 1
FROM old_database.OldDoc ol
JOIN new_database.User u ON u.NAME = ol.operator
JOIN new_database.Location loc ON loc.NAME = ol.lokalizacja;
Maybe LEFT JOIN needed (if some row have no according value in User or Location).
Of course NAME in both ref. tables must be unique.
For "column .. cannot be NULL" - alter table definition and add correct DEFAULT value to each column mentioned in the errors list.
I have a query that gets data and also joins another table (A) and counts the rows in that join table (B). However if the main table (A) is empty I want the query to return nothing. However it is returning a result of null for id and date and an integer value of 0 for users instead of a null row. How do I get an empty result instead of it returning something?
Returning:
id | date | users
null | null | 0
SQL Code
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
An aggregate query without a group by clause always returns a single record, regardless of the content of the underlying result set (and even if it is empty).
But, since you have non-aggregated columns in the select clause (sessions.id and sessions.date), your query is missing a group by clause anyway. In non-ancient versions in MySQL, where sql mode ONLY_FULL_GROUP_BY is enabled by default, this is a syntax error.
Consider:
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
GROUP BY
`sessions`.`id`,
`sessions`.`date`
This will produce one record per session id and date, along with the count of matching records in sessions_users. If there are no records in sessions, the query will return an empty result set.
If I understand correctly, instead of NULL, you want something like this:
id | date | users
| | 0
If so, just simply use IFNULL() in your SELECT as such:
SELECT
IFNULL(`sessions`.`id`,' ') as id,
IFNULL(`sessions`.`date`,' ') as date,
....
There are also a few other ways to achieve this using just IF() or CASE .. but IFNULL is very straight forward.
BUT if you don't want to see any NULL and 0 values, change your LEFT JOIN to INNER JOIN and you're done.
From your description, it sounds like you want an inner join:
SELECT s.id, s.date, COUNT(*) as users
FROM sessions s JOIN
sessions_users su
ON su.id = su.sessions_id;
I have 2 MySQL tables in which I get data from in one query
"tables" table:
"checks" table:
The query I have been trying and the result of it:
SELECT tables.tableName, tables.tableRes, tables.tableResFor, checks.chkID, checks.chkDate, checks.chkStatus
FROM tables
LEFT JOIN checks ON tables.tableID=checks.chkTable
WHERE tables.tableID=3
ORDER BY checks.chkStatus DESC, checks.chkID ASC
Here are the problems
If there were no results from the query, I need the tableName column which comes out never null, so other columns can be null (works now)
I don't want to get the rows after first row, if the chkStatus column is 1 or 0 or null, shortly I need the rows with 2 on chkStatus, if the first row is 0, 1 or null, I don't need the other rows...
Thanks in advance, I have been working on this problem for more than 10 hours...
I need the other checks where chkStatus is 2 so, add the condition to the join
SELECT
tables.tableName
, tables.tableRes
, tables.tableResFor
, checks.chkID
, checks.chkDate
, checks.chkStatus
FROM tables
LEFT JOIN checks ON tables.tableID = checks.chkTable AND chkStatus = 2
WHERE tables.tableID = 3
I am trying to update a value to be NULL where tracker_unique_id can be found in ab_split_tracker_unique_link where that ones ab_split_id can be found in a 3rd table ab_split_candidate.
I cant do it by giving it different values as they can be different from user to user on locals
UPDATE trustpilot_links SET `invite_after_enquiry` = NULL
WHERE EXISTS (
SELECT tracker_unique_id, ab_split_tracker_unique_link.ab_split_candidate_id
FROM ab_split_tracker_unique_link
WHERE EXISTS (
SELECT ab_split_candidate_id
FROM ab_split_candidate LEFT JOIN ab_split
ON ab_split_candidate.ab_split_id = ab_split.ab_split_id WHERE ab_split.reference="review_invite_after_enquiry"
)
);
Edit:
Table examples
Trustpilot Links
trustpilot_link_id | invite_after_enquiry | tracker_unique_id
1 1 123
2 0 1234
ab_split_tracker_unique_link
tracker_unique_id | ab_split_id
1234 32
Ab Split
ab_split_id | reference
32 review_invite_after_enquiry
I want to set values to null if there tracker cannot be found in table ab_split_tracker_unique_link with an ab_split_id that is equal to review_invite_after_enquiry in ab_split
Your subqueries are not related to their parent queries as they should be. Let's look at your inner-most query:
SELECT ab_split_candidate_id
FROM ab_split_candidate
LEFT JOIN ab_split ON ab_split_candidate.ab_split_id = ab_split.ab_split_id
WHERE ab_split.reference = 'review_invite_after_enquiry'
Well, first of all your WHERE clause dismisses outer-joined records, so this is essentially an INNER JOIN. But then: either there are such records or not. This has nothing to do with the record your are potentially updating, nor with the ab_split_tracker_unique_link you are looking up.
So either you are updating all records or none.
We would rather expect something like
UPDATE trustpilot_links tl
SET invite_after_enquiry = NULL
WHERE EXISTS
(
SELECT *
FROM ab_split_tracker_unique_link stul
WHERE stul.tracker_unique_id = tl.tracker_unique_id
AND ...
);
So add WHERE clauses that relate the subqueries to their parent queries.
first image of student_detail table,second is image of payment_detail table when i fire the query like
SELECT `student_detail`.`id`,
`student_detail`.`first_name`,
`student_detail`.`last_name`,
`student_detail`.`course`,
`payment_detail`.`id`,
`student_id`,
`inst_paid_date`,
`next_inst_date`,
`paid_installment`,
`next_installment_amount`
FROM `student_detail`,`payment_detail`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`) from `payment_detail`)
it do not give any result when records are present like second table but if i delete student id 8 and 9 it gives the result other wise not i cant get how it is conflict with other records when perticularly set the where condition with student_id=10. thanks in advanced
The reason is that you limit your inst_paid_date to the maximum value across the entire payment_detail table. Since this maximum value is for student id 9 when it is present, this conflicts with your filter on student id 10.
Try to add the same filter to your subquery like this:
WHERE
...
AND `student_id`='10'
AND `inst_paid_date` in (select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = '10')
A more generic solution would be to turn the subquery into a correlated subquery. This requires an alias on the outer reference to the payment_detail table:
...
FROM `student_detail`,`payment_detail` as `PD`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `PD`.`student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = `PD`.`student_id`)