MySQL left join with 'b's limit - php

First of all, i'm sorry to my wrong english.
I have one question for mysql query join with b.limit
show below two table
Table 1 : Members
id INT NOT NULL PRIMARY KEY
user_name VARCHAR(100) NOT NULL
...
Table 2 : Members_opt
id INT NOT NULL PRIMARY KEY
members_id VARCHAR(100) NOT NULL
category varchar(10) NOT NULL
...
and one user have multiple columns of Members_opt.
and Members.id = Members_opt.members_id.
I want make this query
SELECT * FROM Members a, Members_opt b WHERE a.id = b.members_id;
But this query makes below result.
id | user_name | category
01 | John | cat
01 | John | dog
01 | John | bird
02 | olion | cat
03 | jenny | dog
I want if result have same id value, just add "limit 0,1" to category
so i want this result.
01 | John | cat
02 | olion | cat
03 | jenny | dog
How can I achieve this?

The JOIN operation presents all possible combinations of rows in the two tables. So, if John has a dog, cat, and bird, and you do an ordinary JOIN, you'll get three rows for John.
(SELECT .. FROM a,b WHERE a.something=b.something is a JOIN. It uses old-fashioned syntax but is still a JOIN).
To meet your requirement, you need a way to get a virtual table (a subquery) containing just one pet per member.
SELECT members_id,
MAX(category) category
FROM Members_opt
GROUP BY members_id
will do that. It selects the category (pet) with the name coming last in the alphabet. It returns at most one row per value of members_id.
Then you JOIN that virtual table (subquery) to your other table.
SELECT a.id, a.user_name, b.category
FROM Members a
JOIN (
SELECT members_id,
MAX(category) category
FROM Members_opt
GROUP BY members_id
) b ON a.id = b.members_id
This will return one row for each member showing the chosen category. If a member has no categories (no pets) this query will suppress that member's row. If you want your query to show members having no pets, use LEFT JOIN.
Notice that this query
SELECT * /* incorrect: nonstandard, unpredictable */
FROM Members a, Members_opt b
WHERE a.id = b.members_id
GROUP BY a.id
misuses a nonstandard extension to MySQL's implementation of GROUP BY. It won't work in newer versions of MySQL, but rather will get an error. It will, if it does work at all, return unpredictable results. Read this. https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
Returning unpredictable results is worse than returning random results. When you misuse this GROUP BY hack in MySQL, each subsequent use of the query returns the same results, until it doesn't.

Related

I am working On SQL query but not working full outer join

I want to work on SQL. inner join is not working missing. I am using two tables get data on "city_id " field these table code so please help me
inventory
==========================================
inventory_id | city_id | title |is_enabled
==========================================
1 | 1 | abc | 1
2 | 1 | bcd | 1
cities
====================================
city_id | city | title
===================================
1 | delhi | abc
2 | nodia | bcd
SELECT * FROM inventory i
INNER JOIN cities c
ON i.city_id = c.city_id
WHERE i.is_enabled = 1
ORDER BY i.inventory_id DESC LIMIT 10;
Some databases (such as MS Access and MySQL) do not support FULL OUTER JOIN.
However, FULL OUTER JOIN is rarely needed -- and almost never when you are using keys defined between tables. Well structured databases have keys with appropriate values.
I suspect an INNER JOIN does what you want:
SELECT . . . -- list out the columns you want
FROM inventory i INNER JOIN
cities c
ON i.city_id = c.city_id
WHERE i.is_enabled = 1
ORDER BY i.inventory_id DESC
LIMIT 10;
This query assumes that the inventory rows have a valid city_id. If some are NULL (an allowed, non-matching value), you can use LEFT JOIN instead.
Some other notes:
List out the columns you want explicitly. In particular, duplicate column names can be problematic.
Use table aliases, so the query is easier to write and to read.
Qualify all column names. I'm guessing that is_enabled comes from inventory. I should not have to guess.
Do not put single quotes around numeric constants. I am guessing that is_enabled is a number, not a string.

How to get information from 2 different tables in PHP

I am trying to write a query for my sports pick application. I want to display all the information from one table, along with 2 columns from another table. I can write the query that selects all the information from one table, but I am having a difficult time writing the query to add the 2 rows to my answer. Here are the two tables that I am using. This is all in Postgresql by the way.
I want to select everything from this table.
Table "public.weekly_stats"
Column | Type | Modifiers
---------+-----------------------+--------------------
week_no | integer | not null
game_no | integer | not null
home | character varying(40) |
away | character varying(40) |
spread | double precision | not null default 0
winner | character varying(40) |
Indexes:
"weekly_stats_pkey" PRIMARY KEY, btree (week_no, game_no)
Foreign-key constraints:
"weekly_stats_away_fkey" FOREIGN KEY (away) REFERENCES team(name)
"weekly_stats_home_fkey" FOREIGN KEY (home) REFERENCES team(name)
And then I want to display the wins and losses for each team. That uses this table...
Table "public.team"
Column | Type | Modifiers
--------+-----------------------+--------------------
name | character varying(40) | not null
wins | integer | not null default 0
losses | integer | not null default 0
Indexes:
"team_pkey" PRIMARY KEY, btree (name)
Referenced by:
TABLE "weekly_stats" CONSTRAINT "weekly_stats_away_fkey" FOREIGN KEY (away)
I can select all the information from the first table
Select week_no, game_no, home, wins, losses, away, wins, losses, spread, winner from weekly_stats inner join team on name.team = weekly_stats.team;
The SQL you posted is trying to use a field weekly_stats.team which doesn't exist. The teams are in weekly_stats.home and weekly_stats.away and since you have two of them, you need two joins.
And to join the same table twice, you need to give it an alias. Here this is done by adding team1 or team2 after the actual name of the table in the joins:
Select
weekly_stats.week_no,
weekly_stats.game_no,
weekly_stats.home,
team1.wins,
team1.losses,
weekly_stats.away,
team2.wins,
team2.losses,
weekly_stats.spread,
weekly_stats.winner
from weekly_stats
inner join team team1 on team1.name = weekly_stats.home
inner join team team2 on team2.name = weekly_stats.away ;
Inner join will work. If there is any possibility that the table team might be missing a team, you could change it to left join which will give you a NULL for the wins/losses where data is missing in the team table.
See if this is what you want:
SELECT `weekly_stats.*`, SUM(`team.wins`), SUM(`team.losses`)
FROM `weekly_stats`
INNER JOIN `team`
ON `team.name` = `weekly_stats.team`
If I misunderstood you, I'm really sorry.

MySQL multiple WHERE condition

I'm trying to get this output with MySQL:
-Kate
-William
-dog
(3 results)
From those databases:
--------------- ----------------------
| users | | pet |
|-------------| |------|------|-------
| id | Name | | user|animal|number|
|-------------| |------|------|------|
| 1 |Kate | | 1 | cat | 0 |
| 2 |William| | 2 | dog | 1 |
--------------- ----------------------
Number needs to be != 0
and I need to be able to make the difference between a fetch where number = 0 and number != 0
SELECT
name, animal
FROM
users
INNER JOIN pet ON users.id = pet.user
WHERE
number != 0'
I can't get 'Kate' because never matching != 0.
I think I should use 2 different WHERE conditions in one request, but I don't know how...
First give your tables an alias because you have a ambigious column name id.
SELECT u.name, p.animal
FROM users AS u
INNER JOIN pet AS p
ON u.id = p.id
WHERE p.number != 0
But what you asking for is to get results from both tables without join, right? Like this
SELECT
name AS creatur,
'users' AS type
FROM users
UNION
SELECT
animal AS creatur,
'pet' AS type
FROM pet
WHERE number != 0
First. Use aliases for tables. Use, for example, 'u' for users table and 'p' for 'pet'. Mysql do not understand which field get from which table without aliases.
Second. Condition in WHERE section not related to JOIN. Use AND in ON section.
Third. Use LEFT JOIN instead of INNER JOIN and read articles about types of JOIN and differency between them.
Fourth. In such cases in users table usually adding field pet_id. Do not use single id field for both entities. This thing named ONE-TO-MANY relation. If you want use MANY-TO-MANY relation, you must add third table with two fields user_id and pet_id.
But this query may solve your question:
SELECT u.Name, p.animal
FROM users AS u
LEFT JOIN pet AS p ON u.id = p.user AND p.number != 0

PHP MySQL Select ID from one table and information from another table

I have two tables, one table is called queuelist and the other is call info. In the queuelist table it just lists different IDs. I am trying to get the 'clientID' from that table and match it with the 'ID' in the other table that contains all of the info and display it back on the page. Here is how the tables look:
Table - queuelist
ID | clientID
-------------
1 | 589
2 | 254
3 | 486
Table - info
ID | Name | Phone
--------------------
256 | Bob | 5551231234
486 | Jack | 5551231234
589 | Jill | 5551231234
This is what they call joining tables, you should use a query like this:
SELECT i.ID, i.Name, i.Phone FROM `queuelist` AS q
LEFT JOIN `info` AS i ON (
q.clientID = i.ID
);
I'm using aliases for shorter notation in the above query (queuelist becomes q and info becomes i) and then set the join condition (the bit between the ON()) to be the clientID from the queuelist table should match the ID in the info table.
Also see http://dev.mysql.com/doc/refman/5.0/en/join.html for more details.
You need to use an inner join
select * from queuelist as ql inner join info as i on ql.clientID = i.ID
Though you might want to replace * with specific field names e.g
select ql.clientID, i.fieldname FROM....
Well, I see no difficulty in this using a JOIN.
SELECT * FROM queuelist JOIN info ON clientID = info.ID WHERE queuelist.ID = 2
"Where" would be another option.
SELECT Name, Phone FROM queuelist,info WHERE clientID = ID
Assuming you want only name and phone

MySQL inner join on two columns

I have two tables, books and authors. books has a author_id column and a secondary_author_id column (no books have more than two authors). I'm so far doing:
SELECT * FROM books
LEFT JOIN authors
ON books.author_id=authors.id
which is handling the join with the first author. I can't work out how I'd handle the secondary author though. Should I change my schema, or do I just need a bit of SQL help?
SELECT books.*, author1.*, author2.*
FROM books
LEFT JOIN author AS author1
ON author1.author_id = books.author_id
LEFT JOIN author AS author2
ON author2.author_id = books.secondary_author_id
In SQL, you can alias the tables by adding it after the table name. Just be careful, now you'll have duplicate columns, so instead of author1.* you will probably want to alias the results of both author1 and author2.
EDIT
Additional details -- Say you have your basic table (i'll include the details so if people want to test on their own they can):
CREATE DATABASE test;
USE test;
CREATE TABLE books
(
book_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
author_id INT NOT NULL,
secondary_author_id INT
);
CREATE TABLE authors
(
author_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
);
INSERT INTO authors (author_id,name) VALUES (1,'Sue Z. Que'),(2,'John Doe'),(3,'Bob Smith');
INSERT INTO books (book_id,title,author_id,secondary_author_id) VALUES (1,'JOIN-ing Two Tables',1,2);
If you do the select I mention above, your result will be the following:
|----------------------- books TABLE -----------------------------|---- authors table -----|---- authors table ---|
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
| book_id | title | author_id | secondary_author_id | author_id | name | author_id | name |
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
| 1 | JOIN-ing Two Tables | 1 | 2 | 1 | Sue Z. Que | 2 | John Doe |
+---------+---------------------+-----------+---------------------+-----------+------------+-----------+----------+
(I've added the top header just for calrity's sake) you see you have two author_id's and two name's (as they are joins of the same table and same column names). BUT, if you alias the columns from the joins like so:
SELECT books.*, author1.name AS primary_author, author2.name AS secondary_author
FROM books
LEFT JOIN authors AS author1
ON author1.author_id = books.author_id
LEFT JOIN authors AS author2
ON author2.author_id = books.secondary_author_id;
You get a much cleaner result:
|----------------------- books TABLE -----------------------------| authors table -|- authors table --|
+---------+---------------------+-----------+---------------------+----------------+------------------+
| book_id | title | author_id | secondary_author_id | primary_author | secondary_author |
+---------+---------------------+-----------+---------------------+----------------+------------------+
| 1 | JOIN-ing Two Tables | 1 | 2 | Sue Z. Que | John Doe |
+---------+---------------------+-----------+---------------------+----------------+------------------+
SELECT books.* FROM books, authors.name, secondary_authors.name
LEFT JOIN authors
ON books.author_id=authors.id
LEFT JOIN authors as secondary_authors
ON books.secondary_author_id=secondary_authors.id
You need to rethink your design, because one day there will be a book with three authors, and the next day there will be a book with zero. (I've been there myself.)
Edit
As your comment says: yes, you need a books_authors table. As long as you have your indexes set up properly, it's not a big performance hit.
The most annoying part is that you're often going to want to string the authors together (one entry per book, concatenating all the authors into a single column). You'll probably end up creating a view for that.
just do another join on the secondary id

Categories