SQL: Put rows at top of query if a column exists elsewhere - sql

I have a rows in a table that multiple users will view. Users can "favorite" a row, which adds the username/row key to a separate table.
I want to make a query that orders "favorites" to the top. I assume this would require a subquery, but I'm not sure on the best way to proceed.
One idea I had was to query my table where it exists in favorites, and then union all to a query where it doesn't exist in favorites. But I'm wondering if there's a better way.

You would want something like this:
select t.*
from t left join
favorites f
on t.pk = f.pk and f.userid = #userid
order by (case when f.pk is not null then 1 else 2 end);
pk is the primary key of the original table used to uniquely identify each row.

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!

Performing a query on a foreign table but returning only the original table?

Let's say I have a Item and Person table, where the Person 'id' column matches the Item 'person_id' column. I want to retrieve records in the Item table where the owner (Person) of the Item has 'category' 1. Sample structure below:
Item
id
item_name
person_id
Person
id
name
category (can be 1, 2, or 3)
I understand that I can use 'join' to find rows of the Item table where the two ids match, but I cannot use join for my use case. I need my SQL query to return only Item columns, and not Person columns. Basically, how can I construct a query that will query a table using values in another table, while still maintaining the original table structure?
I understand that I can use 'join' to find rows of the Item table where the two ids match, but I cannot use join for my use case. I need my SQL query to return only Item columns, and not Person columns.
This statement is just false. You can select whatever columns you want when joining:
select i.*
from items i join
persons p
on i.person_id = p.id and p.category = 1;
In terms of constructing the query, exists is also a very reasonable approach, but you can definitely use join.
One way is using EXISTS with correlated subquery
SELECT *
FROM Item i
WHERE EXISTS (SELECT 1
FROM Person p
WHERE p.id = i.person_id AND p.category = 1)
You could use IN clause to filter the person table with category 1
SELECT * FROM Item WHERE person_id IN (
SELECT Id FROM Person WHERE category=1)

How can I order by a specific order?

It would be something like:
SELECT * FROM users ORDER BY id ORDER("abc","ghk","pqr"...);
In my order clause there might be 1000 records and all are dynamic.
A quick google search gave me below result:
SELECT * FROM users ORDER BY case id
when "abc" then 1
when "ghk" then 2
when "pqr" then 3 end;
As I said all my order clause values are dynamic. So is there any suggestion for me?
Your example isn't entirely clear, as it appears that a simple ORDER BY would suffice to order your id's alphabetically. However, it appears you are trying to create a dynamic ordering scheme that may not be alphabetical. In that case, my recommendation would be to use a lookup table for the values that you will be ordering by. This serves two purposes: first, it allows you to easily reorder the items without altering each entry in the users table, and second, it avoids (or at lest reduces) problems with typos and other issues that can occur with "magic strings."
This would look something like:
Lookup Table:
CREATE TABLE LookupValues (
Id CHAR(3) PRIMARY KEY,
Order INT
);
Query:
SELECT
u.*
FROM
users u
INNER JOIN
LookupTable l
ON
u.Id = l.Id
ORDER BY
l.Order

View new count column

I have 2 tables. One who is like a transactional table
userId category
Second table also has
userId (as primary key)
and other columns (not important)
I wanted to create a view based on these 2 tables. Also, I want to have one column which puts into the cells the count from the transactional table who has the same id and eventually matches a special categorie f.e "car".
I thought of maybe using nested select statement, but since i'm a beginner i'm a little bit confused.
Try something like this.
select count(b.userId) as ID, b.category from table2 a inner join transactional b
on a.userId = b.userId where b.category= 'car' group by b.category;

SQL Query to fetch information based on one or more condition. Getting combinations instead of exact number

I have two tables. Table 1 has about 750,000 rows and table 2 has 4 million rows. Table two has an extra ID field in which I am interested, so I want to write a query that will check if the 750,000 table 1 records exist in table 2. For all those rows in table 1 that exist in table 2, I want the respective ID based on same SSN. I tried the following query:
SELECT distinct b.UID, a.*
FROM [Analysis].[dbo].[Table1] A, [Proteus_8_2].dbo.Table2 B
where a.ssn = b.ssn
Instead of getting 750,000 rows in the output, I am getting 5.4 million records. Where am i going wrong?
Please help?
You're requesting all the rows in your select if b.UID is a unique field in column two.
Also if SSN is not unique in table one you can get the higher row count than the total row count for table 2.
You need to consider what you want from table 2 again.
EDIT
You can try this to return distinct combinations of ssn and uid when ssn is found in table 2 provided that ssn and uid have a cardinality of 1:1, i.e., every unique ssn has a single unique uid.
select distinct
a.ssn,b.[UID]
from [Analysis].[dbo].[Table1] a
cross apply
( select top 1 [uid] from [Proteus_8_2].[dbo].[Table2] where ssn = a.ssn ) b
where b.[UID] is not null
Try with LEFT JOIN
SELECT distinct b.UID, a.*
FROM [Analysis].[dbo].[Table1] A LEFT JOIN [Proteus_8_2].dbo.Table2 B
on a.ssn = b.ssn
Since the order detail table is in a one-many relationship to the order table, that is the expected result of any join. If you want something different, you need to define for us the business rule that will tell us how to select only one record from the Order detail table. You cannot effectively write SQL code without understanding the business rules that of what you are trying to achieve. You should never just willy nilly select one record out of the many, you need to understand which one you want.