SQL show the same id in 2 pages - sql

I have "users" table in sql.
id | name | sex | looking4 | status | age
---+---------+-----+----------+--------+-----
1 | omer | 1 | 2 | 3 | 24
2 | yossi | 1 | 3 | 3 | 26
3 | nitzan | 2 | 1 | 3 | 25
sex:
1 - men
2 - girl
I have this sql:
SELECT id, name, city, age, birthday, sex, online
FROM `users`
WHERE `active`='1' AND (`status` IN (7,8,9,109,110)) AND (`age` between 18 AND 55)
AND (`sex`='1' AND `looking4`='3') OR (`sex`='1' AND `looking4`='2') OR (`sex`='2' AND `looking4`='2') OR (`sex`='2' AND `looking4`='3')
ORDER by online desc
LIMIT 10, 10
The problem:
My website show duplicate ids
User id 40 in page 1
User id 40 in page 2
How can I fix my sql query?

Your table data is missing some columns. What is in the column online? Additionally what is the primary key in your table users. Maybe it is natural that you have duplicate keys.
You should ask yourself: What data do I want to display? and What order is required?
Try the following to find out more about the duplicates: ORDER BY ID, online DESC

online sounds like a flag. That means that the sorting is unstable. I would suggest adding an additional column so the sorting is repeatable:
order by online, id

Related

Sum of a column value of table B in table A, is there a automated way ? Is it good practice ? - Oracle SQL

Basically each user has a team, and each team has 11 players, so whenever a player scores they earn some points. Now is there a automated way to do this -
As in when there is a update/entry in the USER_TEAM_PLAYERS table, summate the points of all players to the USER_TEAM table for the corresponding user in some column (in this case TEAM_TOTAL column).
I have two tables:
USER_TEAM with columns USER_ID, TEAM_TOTAL
USER_TEAM_PLAYERS with columns PLAYER_NAME, PLAYER_POINTS, USER_ID
Example:
TABLE - USER_TEAM
USER_ID | TEAM_TOTAL
---------------------
1 | 40
2 | 50
TABLE - USER_TEAM_PLAYERS
PLAYER_NAME | PLAYER_POINTS | USER_ID
-------------------------------------
Adam | 10 | 1
Alex | 30 | 1
Botas | 40 | 2
Pepe | 5 | 2
Diogo | 5 | 2
The first table should be only a view of the second one
CREATE VIEW USER_TEAM2 AS
SELECT USER_ID, SUM(PLAYER_POINTS) AS TEAM_TOTAL
FROM USER_TEAM_PLAYERS
GROUP BY USER_ID
ORDER BY USER_ID;
Doing this, you have no duplicate data and a view can be in SELECT, ... like a table.
Nota 1 : I used the name USER_TEAM2 because your first table still exists but you can delete it.
Nota 2 : If you want to have some specific data to the TEAM_TABLE, keep the 2 names, and modifify your view as needed by adding some fields with a JOIN of this first table.

SQL Server query - don't want multiple rows with identical data

I have a SQL Server database that has the following three tables - this is simplified for this post.
Stakeholder table (a table that stores a persons personal data... name, address city, state, zip, etc)
Stakeholder_id full_name
---------------------------------------
1 Joe Stakeholder
2 Eric Stakeholder
SH Inquiry table (a table that stores information about when a stakeholder contacts us)
sh_inquiry_id inquiry_link_ID
-----------------------------------------------
1 1
2 1
3 2
Sh Contacts (a table that stores information about when we contact a stakeholder)
sh_contact_id contact_link_id
-----------------------------------------
1 1
2 1
3 2
I want to write a SQL query that shows the stakeholder information once then show all inquiries and all contacts underneath the stakeholder row? is that possible with SQL? So in this case joe stakeholder would be shown once and then there would be 4 rows next (2 inquiries and 2 contacts). Eric stakeholder would be shown once with two rows, 1 inquiry and one contact.
Thanks for any assistance in advance.
As has already been mentioned, you probably want to handle this in your application code. However, you can use a UNION query to sort of do what you want.
With the query below, I changed your latter 2 tables to SH_Inquiry and SH_Contacts (replaced spaces with underscores), which is generally a good habit (it's a bad idea to have spaces in your object names). Also, depending on how your tables are laid out, you might want to merge your Contacts and Inquiry tables (e.g. have one table, with a contact_type field that identifies it as "inbound" or "outbound").
Anyways, using a CTE and union:
WITH Unionized AS
(
SELECT
stakeholder_id,
full_name,
NULL AS contact_or_inquiry,
NULL AS contact_or_inquiry_id
FROM Stakeholder
UNION ALL
SELECT
inquiry_link_id AS stakeholder_id,
NULL AS full_name,
'inquiry' AS contact_or_inquiry,
sh_inquiry_id AS contact_or_inquiry_id
FROM SH_Inquiry
UNION ALL
SELECT
contact_link_id AS stakeholder_id,
NULL AS full_name,
'contact' AS contact,
sh_contact_id AS contact_or_inquiry_id
FROM SH_Contacts
)
SELECT
full_name,
contact_or_inquiry,
contact_or_inquiry_id
FROM Unionized
ORDER BY
stakeholder_id,
contact_or_inquiry,
contact_or_inquiry_id
giving you these results:
+------------------+--------------------+-----------------------+
| full_name | contact_or_inquiry | contact_or_inquiry_id |
+------------------+--------------------+-----------------------+
| Joe Stakeholder | NULL | NULL |
| NULL | contact | 1 |
| NULL | contact | 2 |
| NULL | inquiry | 2 |
| Eric Stakeholder | NULL | NULL |
| NULL | contact | 3 |
| NULL | inquiry | 1 |
| NULL | inquiry | 3 |
+------------------+--------------------+-----------------------+

Show id's that only contain one kind of name

Here is a table which will help me to explain the question.
id | name
----|--------------
1 | John
1 | John
1 | Arya
2 | Tyrion
2 | Tyrion
3 | Jamie
3 | Cersie
I need to make a SQL query that only shows id 2 because it only contains one kind of name.
1 and 3 will not be shown because they have 2 different names.
1 would have been shown if Arya would have been John, because then 1 would only contain Johns.
Group by the id - the column you want to be unique. Then take only those groups having one distinct name
select id
from your_table
group by id
having count(distinct name) = 1

Postgres Many to many mapping sql query

Postgresql Database
Table User
-----------
ID | Name
1 | John
2 | Bob
3 | Sarah
Table Photo
-------------
ID | Caption
1 | Vacation
2 | Birthday
3 | Christmas
Table Comment
--------------
ID | User ID | Photo ID| Text
1 | 1 | 1 | Mexico Looks Great
2 | 2 | 1 | Sure Does
3 | 3 | 1 | Too Hot
4 | 1 | 2 | Look at that cake
5 | 3 | 2 | No ice cream?
6 | 1 | 3 | So Happy
Desire: I want to get all the photos that ONLY John(1) and Sara(3) commented on.
How do I build a SQL query that looks for photos that only have comments from user #1 and user #3, I want to EXCLUDE results where more(or less) than those two commented on.
The clearest and most readable way, is the Photos containing comments by:
User1 Intersect User2 Except Any other user
This SQL Fiddle and query will return that:
SELECT *
FROM Photo
WHERE ID IN (
SELECT "Photo ID" FROM Comment WHERE "User ID" = 1
INTERSECT
SELECT "Photo ID" FROM Comment WHERE "User ID" = 3
EXCEPT
SELECT "Photo ID" FROM Comment WHERE "User ID" NOT IN (1, 3)
)
lets do three joins, one for john, one for sara, one for everyone else. Then we'll limit what we get back with the where clause.
select p.*
from photo p
left join comment john on john.photo_id=p.photo_id and john.user_id=1
left join comment sara on sara.photo_id=p.photo_id and sara.user_id=3
left join comment everyone_else on everyone_else.photo_id=p.photo_id and everyone_else.user_id<>3 and everyone_else.user_id<>1
where
everyone_else.id is null
and john.id is not null
and sara.id is not null
There are a couple of ways to do this. One is to use count with case:
select photoid
from comment
group by photoid
having count(distinct userid) = 2
and count(case when userid not in (1,3) then 1 end) = 0
SQL Fiddle Demo
Basically, make sure 2 users have commented and then make sure only user 1 or 3 commented.
You could use an intersection to find only the common photos, which would exclude photos commented by John but not Sarah, or vice versa
select photo_id from comment where user_id = 1
intersect
select photo_id from comment where user_id = 3

Problem with advanced distinct SQL query

Ok this one is realy tricky :D
i have a this table
bills_products:
- bill_id - product_id - action -
| 1 | 4 | add |
| 1 | 5 | add |
| 2 | 4 | remove |
| 2 | 1 | add |
| 3 | 4 | add |
as you can see product with the id 4 was added at bill 1 then removed in bill 2 and added again in bill 3
All Bills belong to a bill_group. But for the simplicity sake let's assume all the bills are in the same group.
Now i need a SQL Query that shows all the products that are currently added at this group.
In this example that would be 5, 1 and 4. If we would remove the bill with id 3 that would be 5 and 1
I've tried to do this with DISTINCT but it's not powerful enough or maybe I'm doing it wrong.
This seems to work in SQL Server at least:
select product_id
from (
select product_id,
sum((case when action='add' then 1 else -1 end)) as number
from bills_products
group by product_id
) as counts
where number > 0
SELECT DISTINCT product_id FROM bills_products WHERE action = 'add';
GSto almost had it, but you have to ORDER BY bill_id DESC to ensure you get the latest records.
SELECT DISTINCT product_id FROM bills_products
WHERE action = 'add'
ORDER BY bill_id DESC;
(P.S. I think most people would say it's a best practice to have a timestamp column on tables like this where you need to be able to know what the "newest" row is. You can't always rely on ids only ascending.)