Output identical fields names of two LEFT JOIN tables Sql - sql

I have two tables, with about 20 columns each
users:
id_user user ..... status token
----------------------------------
2 A 0 XdAQ
posts:
id_user post ..... status token
-------------------------------------
3 hi 1 sDyTMl
Query:
SELECT u.*,p.*
FROM posts as p
LEFT JOIN users as u ON u.id_user = p.id_user
WHERE p.id_post = 3
LIMIT 1
So in Php, it could be retrieved any value
....
$status=$a['status'];
$token=$a['token'];
I want to return all the fields of each table to make the post content, the problem is that there is conflict among those identical column names in each table. there are more than 20 columns in each in my real tables, so writing the column names with aliases I think is not the way to go. Is there a way to alias only those identical columns in conflict?

You really should list the specific columns that you want. This is the safest way to retrieve values from the table.
If the only column that is in common is the one used for the join, you can use the USING clause:
SELECT *
FROM posts p LEFT JOIN
users as u
USING (id_user)
WHERE p.id_post = 3
LIMIT 1;
The USING clause is ANSI standard, but not all databases support it. When you use it, only one version of id_post is in the columns returned by the SELECT *. In a LEFT JOIN, it is the version with a value.
If you have other columns with the same name, you need to use column aliases. One short-cut is to take all columns from one table and name the columns in the other:
SELECT u.*, p.col1 as p_col1, . . .
FROM posts p LEFT JOIN
users as u
USING (id_user)
WHERE p.id_post = 3
LIMIT 1;

Related

SQL select with three tables

Hi guys I'm new with databases and I'm trying to make a query where I join 3 tables. I could make it and I want to clean up the result. I want to know how can I delete the column "pin" from users table and maybe some "ids" columns.
Select * from "wish-list"
Join products
On "wish-list".id = products.holiday_id
Join users
On "wish-list".user_id = users.id
Where "wish-list".id = 1
You need to specify which columns you really need in your output. At the moment you are using
SELECT * which outputs all columns of all joined tables.
Here is what it should look like:
SELECT holiday, products.description, users.pin FROM "wish-list"
JOIN products ON "wish-list".id = products.holiday_id
JOIN users ON "wish-list".user_id = users.id
WHERE "wish-list".id = 1
It's important that you reference all columns which are not your main entity (here wish-list) with tablename.column (products.description and not only description). It will work without referencing strictly but only if the column name is unique in your query.
Furthermore you can rename columns. This is useful for example if you want to get the id's of the product table and the wish-list table.
SELECT product.id AS product_id, id AS wishlist_id FROM "wish-list"
...
Hope that helps!

LEFT JOIN on mismatches

If I have table 1 called "FILES" and table 2 called "Networks" and the value that goes in FILES.Network_ID must be from a list defined in Networks.Network_ID
If I wanted to run a query to find out if there are any values under network_id in table 1 that are not defined in table 2, I tried the below which doesn't work apparently...Also, I'm using the SQL view of MS ACCESS
SELECT *
FROM (FILES f LEFT JOIN Networks
ON f.Network_ID <> Networks.Network_ID)
This query won't work properly because your are trying to join if the ids don't match, so ideally while making join the rows will match
For instance if table Files contains rows with network id 1,2,3 and table Networks contains network id 1,2 then upon joining you will get a combination of rows with network ids [1,2], [2,1],[3,1],[3,2].
Instance if you use a subquery and then filter it using IN clause will work
select * from files where network_id not in (select network_id from networks);
Try this
SELECT *
FROM (FILES f LEFT JOIN Networks
ON f.Network_ID =Networks.Network_ID)
Where Networks.Network_ID Is Null
To ensure data integrity create a relationship between both tables.

SQL SELECT * FROM 2 tables

I am building a small database app for friends where table 1 is contacts and table 2 is users. I can find email on both (One as the loggued in user and the other as the owner of the contact)
SELECT *
FROM contacts
WHERE contacts.username = users.email
I try to show all contacts fields where username is equal to already loggued in users (email)
Thanks you very much!
It sounds like you're trying to JOIN two tables together. Ideally, you don't want to use the email as the primary key on a table (the smaller the data, the faster your JOIN will be); a better option would be to add an auto-incrementing Id (integer) to both the Contacts and Users tables, set as the primary key (unique identifier). Joining on integers is much faster, as integers are 4 bytes per row, vs string which (in MySQL) is 1 per character length (latin1 encoding) + 1 byte.
Anyway, back to the original question. I believe the query you're looking for (MySQL syntax) is:
SELECT c.Id, c.Col1, u.Col2, ...
FROM contacts AS c
INNER JOIN users AS u ON u.email = c.username
Additionally, I would avoid the use of *, as it slows down the query a bit. Instead, try to specify the exact columns you need.
Try the following. Also, I would suggest you learn about joins in SQL.
SELECT *
FROM contacts
INNER JOIN
users on contacts.username = users.email
Use Inner Join:
SELECT *
FROM contacts as c
INNER JOIN
users as u on u.email = c.username

Doing a FULL OUTER JOIN in Sqlite3 to get the combination of two columns?

I'm currently working on a database project and one of the problems calls for the following:
The Genre table contains twenty-five entries. The MediaType table contains 5
entries. Write a single SQL query to generate a table with three columns and 125
rows. One column should contain the list of MediaType names; one column
should contain the list of Genre names; the third column should contain a count of
the number of tracks that have each combination of media type and genre. For
example, one row will be: “Rock MPEG Audio File xxx” where xxx is the
number of MPEG Rock tracks, even if the value is 0.
Recognizing this, I believe I'll need to use a FULL OUTER JOIN, which Sqlite3 doesn't support. The part that is confusing me is generating the column with the combination. Below, I've attached the two methods I've tried.
create view T as
select MediaTypeId, M.Name as MName, GenreId, G.Name as GName
from MediaType M, Genre G
SELECT DISTINCT GName, MName, COUNT(*) FROM (
SELECT *
FROM T
OUTER LEFT JOIN MediaType
ON MName = GName
UNION ALL
SELECT *
FROM Genre
OUTER LEFT JOIN T
) GROUP BY GName, MName;
However, that returned nearly 250 rows and the GROUP BY or JOIN(s) is totally wrong.
I've also tried:
SELECT Genre.Name as GenreName, MediaTypeName, COUNT(*)
FROM Genre LEFT OUTER JOIN (
SELECT MediaType.Name as MediaTypeName, Track.Name as TrackName
FROM MediaType LEFT OUTER JOIN Track) GROUP BY GenreName, MediaTypeName;
Which returned 125 rows but they all had the same count of 3503 which leads me to believe the GROUP BY is wrong.
Also, here is a schema of the database:
https://www.dropbox.com/s/onnbwqfrfc82r1t/IMG_2429.png?dl=0
You don't use full outer join to solve this problem.
Because it looks like a homework problem, I'll describe the solution.
First, you want to generate all combinations of genres and media types. Hint: This uses a cross join.
Second, you want to count all the combinations that you have. Hint: this uses an aggregation.
Third, you want to combine these together. Hint: left join.

Query to ORDER BY the number of rows returned from another SELECT

I'm trying to wrap my head around SQL and I need some help figuring out how to do the following query in PostgreSQL 9.3.
I have a users table, and a friends table that lists user IDs and the user IDs of friends in multiple rows.
I would like to query the user table, and ORDER BY the number of mutual friends in common to a user ID.
So, the friends table would look like:
user_id | friend_user_id
1 | 4
1 | 5
2 | 10
3 | 7
And so on, so user 1 lists 4 and 5 as friends, and user 2 lists 10 as a friend, so I want to sort by the highest count of user 1 in friend_user_id for the result of user_id in the select.
The Postgres way to do this:
SELECT *
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS friends
FROM friends
) f USING (user_id)
ORDER BY f.friends DESC NULLS LAST, user_id -- as tiebreaker
The keyword AS is just noise for table aliases. But don't omit it from column aliases. The manual on "Omitting the AS Key Word":
In FROM items, both the standard and PostgreSQL allow AS to be omitted
before an alias that is an unreserved keyword. But this is impractical
for output column names, because of syntactic ambiguities.
Bold emphasis mine.
ISNULL() is a custom extension of MySQL or SQL Server. Postgres uses the SQL-standard function COALESCE(). But you don't need either here. Use the NULLS LAST clause instead, which is faster and cleaner. See:
PostgreSQL sort by datetime asc, null first?
Multiple users will have the same number of friends. These peers would be sorted arbitrarily. Repeated execution might yield different sort order, which is typically not desirable. Add more expressions to ORDER BY as tiebreaker. Ultimately, the primary key resolves any remaining ambiguity.
If the two tables share the same column name user_id (like they should) you can use the syntax shortcut USING in the join clause. Another standard SQL feature. Welcome side effect: user_id is only listed once in the output for SELECT *, as opposed to when joining with ON. Many clients wouldn't even accept duplicate column names in the output.
Something like this?
SELECT * FORM [users] u
LEFT JOIN (SELECT user_id, COUNT(*) friends FROM fields) f
ON u.user_id = f.user_id
ORDER BY ISNULL(f.friends,0) DESC