Create view from table with multiple primary key - sql

I've a table like this one:
Column | Type | Modifiers
username | character varying(12) | not null
electioncode | integer | not null
votes | integer | default 0
PRIMARY KEY (username, electioncode)
i need to create a view with username, electioncode, max(votes)
if i use this query it works fine but without username:
SELECT electioncode, max(votes) from table group by electioncode;
if i add username it asks me to add it into the group by but if i do that it gives me the entire table instead of just the username-electioncode-maxvotes

Do you want to get username associated with this number of votes? Or any username in given election code?
If the first:
SELECT
DISTINCT ON ( electioncode )
*
FROM table
ORDER BY electioncode, votes desc;
if the other:
SELECT
electioncode,
min(username),
max(votes)
FROM
table
GROUP BY electioncode;

Your username field seems to be unique. Every record has different username (I am assuming) thus when you group by username it will give you all the records. What you are trying to do has a logic issue not syntax issue.
A suggestion: You want to write on a piece of paper the output you would like to see and then construct the query... If you want Username, Electioncode and max (votes) then imagine how you would display the data where two usernames - user1 and user 2 who have electioncode 001 and voted 1 each? How would you display this?

Related

SQL Query to fetch the customers registered in the DB without email address(CS can have phonenumber and email in the same field but duplicating)

I need help with writing this query please ,
in the Database - the customer is registered twice , one row with the email address in the VALUE field and the other row with phone number in the SAME VALUE field .
I want to fetch customer who DO NOT HAVE email address in the VALUE FIELD .
For example , I want to fetch only the last row from the list shown in the figure I shared.
Appreciate your help!
I tried creating multiple SELECT queries , but still not getting the accurate values.
Without seeing table schemas or example data, I'm making an assumption here that you have a field that is common to both rows so you know the customer row with the email value and the customer row with the phone value are linked to the same customer. For the purposes of this example, I'm going to call that field "customer_number".
I'd suggest a query that utilises an auxiliary statement like this:
WITH customers_with_emails AS (
SELECT customer_number
FROM customers
WHERE customer_value LIKE '%#%'
)
SELECT *
FROM customers
WHERE customer_number NOT IN (
SELECT customer_number
FROM customers_with_emails
);
This will return customers with phone numbers, who do not also have an email address.
I suggest that you use the following query, modified with the exact column and table name. We use string_agg to coalesce all the value fields for the same customer id and only show them if none of them contain an # sign.
create table customers(
id int,
name varchar(25),
value varchar(25));
insert into customers values
(1,'Mr A','1234'),
(1,'Mr A','a#b.c'),
(2,'Mr B','6789');
select
id,
max(name) "name",
string_agg(value,', ')
from
customers
group by
id
having
string_agg(value,', ') NOT LIKE '%#%';
id | name | string_agg
-: | :--- | :---------
2 | Mr B | 6789
db<>fiddle here

Can a SQL database support "insert only" mode?

In the latest years the "Insert Only" methodology came more and more popular.
For those who use SQL DB you probably know that in high volume with a lot of update queries the DB is locking the rows and you starting to get a "bottleneck". the Insert Only mode is to use only insert (without updates) and always retrieve the latest item in the DB.
The issue I'm facing is with the SELECT queries since there is a field that can be common for multiple records in the DB and if I will want to query by it I will never know when I got all of the latest records for the field above (unless I'm using GROUP and this will not be efficient)
Scheme Example:
let say I have the following scheme:
CREATE TABLE users
(
id SERIAL NOT NULL
CONSTRAINT users_pkey
PRIMARY KEY,
first_name VARCHAR(255),
last_name VARCHAR(255),
username VARCHAR(255),
email VARCHAR(255),
password VARCHAR(255),
account_id INTEGER,
created_at TIMESTAMP NOT NULL
);
Now let say I have the following users that's related to account number 1 (using account_id):
1. John Doe
2. Jain Doe
If I will want to edit John Doe last name in the Insert Only mode I will insert a new record and when I will want to retrieve it I will run the following query:
SELECT * from users WHERE email='jhon.doe#test.com' ORDER BY created_at Desc limit 1;
The issue is what I need to to if I want to retrieve all account 1 users ? how can I prevent from executing poor query with group by
The following query will return 3 records although I have only 2 users
SELECT * from users WHERE account_id=1;
The answer to your question is distinct on (in Postgres). However, it is unclear how you define a user. I would expect a user_id, but perhaps email is supposed to serve this purpose.
The query looks like:
select distinct on (email) u.*
from users u
where account_id = 1
order by email, created_at desc;
For performance, you want an index on users(account_id, email, created_at desc).

select users with same social security number different badge numbers

Hello as the title suggest I need help writing a query that does this. I need to find all the users who have had a badge number change. So in the database there are often two records for the same person but both have a different badge number. Im assuming it's the same person if the social matches.
Table:
Badge_no | SSN
123123 | 387-47-1234 2
34837 | 387-47-1234
837532 | 543-45-6392
584391 | 543-45-6392
In this case I would want it to output:
837532 | 543-45-6392
584391 | 543-45-6392
Thank you!
I believe the following should do the trick here:
SELECT *
FROM yourtable
WHERE SSN IN (SELECT SSN FROM yourtable GROUP BY SSN HAVING Count(*) >=2);
That subquery will return SSN's that have more than one record. We use those SSN's to select, again, from the table to get all of the fields associated to them.

SQL extract unique data from two columns in same table

I have a table friends, which contains the following columns:
friend_id and friend_of (both are storing unique user ids)
lets say the table friends contains the following data:
friend_id | friend_of
-------------------------
123 | 456
456 | 789
456 | 123
So this means that:
user with id=123 have one friend with id=456
user with id=456 have two friends with ids=123 (friend_1) & 789(friend_2)
user with id=789 have one friwnd with id=456
I want to write a query that given a single user id shows every friend that this user has (with their ids).
For example:
if given user with id=123 the output would be users with ids=456
if given user with id=789 the output would be users with ids=456
if given user with id=456 the output would be users with ids=123 and 789
Can you help me with the query I need?
(select friend_id as all_friends from friends where friend_of=ID)
uninon
(select friend_of as all_friends from friends where friend_id=ID)
I suppose you are interested in the case where an id exists only in one of the columns. Above query would address this. Note that union is used here and not union all as unique values are required.
select friend_id, friend_of
where friend_id = '456'
just change ID to get desire ouput
Just use union
Declare #id int = 1;
select f.friendof from
#YourTableName as f where f.friendId = #id
union
select f.friendId from
#YourTableName as f where f.friendof = #id
You can use the query SELECT * FROM friends WHERE friend_id='456', which should get all of the friends of 456. Then do a join on your "users" table using the foreign key friend_of.
EDIT: I didn't realize friends was a two-way relationship. In that case, use a UNION first, some of the other responses talk about it. :)

SQL table column values to select query list

So I have a table that has EMAIL and Order ID.
EMAIL | id
--------------
Y#a.com | 1
Y#a.com | 2
X#a.com | 3
And I need to SELECT it so that I'd have email column that is distinct and ids column that is array of int's
EMAIL | ids
--------------
Y#a.com | [1,2]
X#a.com | [3]
I use PSQL 9.3. I looked at aggregate functions, but since I'm not too good with SQL atm, I didn't really understand them. My code so far is:
SELECT DISTINCT ON (email) email
FROM order
WHERE date > '2013-01-01';
Use the aggregate function array_agg():
SELECT email, array_agg(id) AS id_array
FROM "order"
WHERE date > '2013-01-01'
GROUP BY email;
Aside: your identifiers ...
Don't use order as table name, it's a reserved word.
Don't use date as column name, it's a reserved word in standard SQL and a basic type name in Postgres.
I wouldn't use id as column name either, that's a common anti-pattern, but "id" is not a descriptive name. Once you join a couple of tables you have n columns named "id" and you need to start dealing out column aliases, not to speak of the confusion it may cause.
Instead, use something like this:
CREATE TABLE order_data (
order_data_id serial PRIMARY KEY
, email text
, order_date date
);