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) - sql

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

Related

DB queries with "In" seem to be sorted

There are clients(companies) and contacts in two tables. Both contacts and clients have their own fields. But they all have an id that is a primaryKey. In addition, there are "links" between clients and contacts - each client can be assigned a contact and vice versa. There is a third table for this, called 'assignment', which has only two fields - company id and contact id.
Suppose we have linked a contact with id 3 to a company with id 12076. Next, we have linked a contact with id 10, and the last contact with id 5. Сheck our result:
SELECT contactId FROM assignment WHERE companyId = 12076;
The result is correct -
After these steps, at some point I need to get the FIELDS of contacts associated with the company I need. There is a company 12076, I need to get all the contact fields associated with it. I made a request like this:
SELECT id, fullName FROM contacts WHERE contacts.rowid IN (SELECT contactId FROM assignment WHERE companyId = 12076);
This request displays the contacts I need and their fields. Exactly 3 contacts, but there is one problem - they are displayed in sorted order, sorted by id.
I need the contact fields to be displayed in the order in which they were added. How can i dow this? Maybe i need to use JOIN?
By default an SQLite table has a Rowid column. We can use this column in ORDER BY.
If we want the ContactId's in the order they were inserted into the table contacts we can join onto contacts and order by it's Rowid.
See [https://www.sqlitetutorial.net/sqlite-autoincrement/][1]
create table companies(id int);
create table contacts (id int);
create table assignment(companyId int,contactId int);
insert into companies values(12076);
insert into contacts values(10),(3),(5);
insert into assignment values (12076,3),(12076,10),(12076,5);
SELECT a.contactId
FROM assignment a
JOIN contacts c
on a.contactId = c.id
WHERE companyId = 12076
order by c.Rowid;
| contactId |
| --------: |
| 10 |
| 3 |
| 5 |
db<>fiddle here

How to use multi table join query efficiently in SQL?

I have Problem statement in Apache Phoenix in which I need to combine three tables for the result.
I have three views over Hbase table, Schema is as follow
Table group:-
pk | Title | ownerId | data
Table Members:-
pk | parentId | Email | data
Table userinfo:-
pk | Email | First Name | Last Name
Now, I want to fetch groups whose title matches with input string if not matched then want to fetch groups whose members have a name that matches with the input string.
I already tried query as follow:-
select * from Group where pk like 'Prefix_%'
and (TITLE like '%A%'
or (OWNER_ID in
(
select parentId from MEMBERS where EMAIL in
( select distinct(EMAIL) from USER_INFO
where pk like 'PREFIX%' and
( FIRST_NAME like '%A%' or LAST_NAME like '%A%')
)
)
) ) order by TITLE limit 5;
But, it's taking too much time also tried Left Join Query with similar but not give expected result.
Please Suggest how can I improve this?

Create a table without knowing its columns in SQL

How can I create a table without knowing in advance how many and what columns it exactly holds?
The idea is that I have a table DATA that has 3 columns : ID, NAME, and VALUE
What I need is a way to get multiple values depending on the value of NAME - I can't do it with simple WHERE or JOIN (because I'll need other values - with other NAME values - later on in my query).
Because of the way this table is constructed I want to PIVOT it in order to transform every distinct value of NAME into a column so it will be easier to get to it in my later search.
What I want now is to somehow save this to a temp table / variable so I can use it later on to join with the result of another query...
So example:
Columns:
CREATE TABLE MainTab
(
id int,
nameMain varchar(max),
notes varchar(max)
);
CREATE TABLE SecondTab
(
id int,
id_mainTab, int,
nameSecond varchar(max),
notes varchar(max)
);
CREATE TABLE DATA
(
id int,
id_second int,
name varchar(max),
value varchar(max)
);
Now some example data from the table DATA:
| id | id_second_int | name | value |
|-------------------------------------------------------|
| 1 | 5550 | number | 111115550 |
| 2 | 6154 | address | 1, First Avenue |
| 3 | 1784 | supervisor | John Smith |
| 4 | 3467 | function | Marketing |
| 5 | 9999 | start_date | 01/01/2000 |
::::
Now imagine that 'name' has A LOT of different values, and in one query I'll need to get a lot of different values depending on the value of 'name'...
That's why I pivot it so that number, address, supervisor, function, start_date, ... become colums.
This I do dynamically because of the amount of possible columns - it would take me a while to write all of them in an 'IN' statement - and I don't want to have to remember to add it manually every time a new 'name' value gets added...
herefore I followed http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/
the thing is know that I want the result of my execute(#query) to get stored in a tempTab / variable. I want to use it later on to join it with mainTab...
It would be nice if I could use #cols (which holds the values of DATA.name) but I can't seem to figure out a way to do this.
ADDITIONALLY:
If I use the not dynamic way (write down all the values manually after 'IN') I still need to create a column called status. Now in this column (so far it's NULL everywhere because that value doesn't exist in my unpivoted table) i want to have 'open' or 'closed', depending on the date (let's say i have start_date and end_date,
CASE end_date
WHEN end_date < GETDATE() THEN pivotTab.status = 'closed'
ELSE pivotTab.status = 'open'
Where can I put this statement? Let's say my main query looks like this:
SELECT * FROM(
(SELECT id_second, name, value, id FROM TABLE_DATA) src
PIVOT (max(value) FOR name IN id, number, address, supervisor, function, start_date, end_date, status) AS pivotTab
JOIN SecondTab ON SecondTab.id = pivotTab.id_second
JOIN MainTab ON MainTab.id = SecondTab.id_mainTab
WHERE pivotTab.status = 'closed';
Well, as far as I can understand - you have some select statement and just need to "dump" its result to some temporary table. In this case you can use select into syntax like:
select .....
into #temp_table
from ....
This will create temporary table according to columns in select statement and populate it with data returned by select datatement.
See MDSN for reference.

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
);

SQL Return Specific Value for Duplicate rows

Here is my issue
I am using bulk import to import a CSV file into a table (InputTable). This table needs to be separated into 3 different tables with distinct values.
Tables are Client, Child Company, Contacts
Client has a one to many relationship to child company as well as to contacts.
The client Table has has two fields (name,status)
it is easy enough to pull in a distinct name from dbo.InputTable using this query...
insert into Client
(
Name
)
select distinct Name
from InputTable
this query will insert data like this
Name
One Company
Two Company
Three Company
However when i try this code
insert into Client
(
Name
,Status
)
select distinct Name
from InputTable
group by Name
,Status
I get this result
Name | Status
One Company | Active
Two Company | Active
Two Company | Terminated
Three Company | Active
Here is the kicker, If client is showing active in one row no matter how many rows then i need to show active for that Name record on the Client Table
if they are showin all terminated then i would need to copy in the terminated status to the client table for that row.
any ideas on how to accomplish this?
Thank you in advance
insert into Client (Name, status)
select name,
min(status) as status
from InputTable
group by name