Count domain names with CTE Table - sql-server-2008

I want to count domain names of emailaddresses where I would like to exclude some of the domain names from my results, but my query is getting timedout so i tried with cte table but its not excluding those domain names.
TRY 1:
I tried without cte table Query is getting timedout due to lot of computations going on.
TRY 2: I tried with CTE table but query is not excluding those domains which are in CTE table. So I am not understanding whats going on as I am not very used to using CTE tables.
Customers Table (This is a dummy dataset, In actual I have a very large dataset)
EmailAddress
xyz#gmail.com
abc1#gmail.com
xyz#yahoo.com
cvbv#yahoo.com
123#comcast.net
cvx1#comcast.net
abv#comcast.net
cxt#msn.com
abcd#msn.com
3453w#att.net
weszt#att.net
wrt#live.com
adcs#live.com
Try 1:
SELECT
Domain = RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress))
,EmailCount = COUNT(DISTINCT c.EmailAddress)
FROM Customers c
WHERE
LEN(c.EmailAddress) > 0
AND RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress))NOT IN ('gmail.com'
,'yahoo.com'
,'comcast.net'
)
GROUP BY RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress))
ORDER BY EmailCount DESC
TRY 2: With CTE
with cte_x as ( SELECT RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress)) AS DOMAIN
FROM Customers c
WHERE LEN(c.EmailAddress) > 0
AND RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress)) NOT IN
('gmail.com'
,'yahoo.com'
,'comcast.net'))
SELECT RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress)) AS DOMAIN_1 ,
COUNT(DISTINCT c.EmailAddress) AS EmailCount
FROM Customers c
LEFT JOIN cte_x ON c.EmailAddress=cte_x.DOMAIN
WHERE cte_x.DOMAIN IS NULL
GROUP BY
RIGHT(c.EmailAddress, LEN(c.EmailAddress) - CHARINDEX('#', c.EmailAddress))
Result Coming:
Domain count
gmail.com 2
yahoo.com 2
comcast.net 3
msn.com 2
att.net 2
live.com 2
Results Expected:
Domain count
msn.com 2
att.net 2
live.com 2

Related

SQL : How can I get count from multiple tables into one query?

I have 3 tables, one for website connection errors, one for successful website connections and another with name/location of each specific website.
Table 1 has WebsiteClass_ID, Website_ID and Error_Date
Table 2 has WebsiteClass_ID, Website_ID and Success_Date
Table 3 has WebsiteClass_ID, Website Name and Location
I need to return the rate of error by WebsiteClass_ID by Website_ID per day. To do this, I need the count of errors per WebsiteClass_ID, Website_ID and Date from Table 1 and the count of successful connections per WebsiteClass_ID, Website_ID and Date from Table 2. I still need to return Website Name and Location from table 3 as well. The date field is different in Table 1 than it is in Table 2.
I can easily get the count for each in two different queries but would prefer to accomplish this in one query to avoid extra work in Excel. I created the two individual queries below but do not know how to merge them.
#QUERY
#TITLE-WEBSEROR
#SUBJECT-WEBSITE ERRORS PER DAY BY CLASS AND ID
SELECT
A.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,A.WEBSITE_ID AS WEBSITE_ID
,A.ERROR_DATE AS DATE_OF_ERROR
,COUNT(A.EVENT_NAME) AS NUMBER_OF_ERRORS
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..ERRORS A
,&DATABASE..DETAILS B
WHERE
A.WEBSITE_ID = B.WEBSITE_ID
GROUP BY A.WEBSITE_CLASS_ID, A.WEBSITE_ID, A.ERROR_DATE, B.NAME, B.LOCATION
#QUERY
#TITLE-WEBSCNFM
#SUBJECT-SUCCESSUL CONNECTIONS PER DAY BY CLASS AND ID
SELECT
C.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,C.WEBSITE_ID AS WEBSITE_ID
,DATE(C.SUCCESS_DATE) AS SUCCESSFUL_CONNECTION
,COUNT(C.SUCCESS) AS COUNT_SUCCESS_CNCTN
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..SUCCESS C
,&DATABASE..DETAILS B
WHERE
C.WEBSITE_ID = B.WEBSITE_ID
GROUP BY C.WEBSITE_CLASS_ID, C.WEBSITE_ID, DATE(C.SUCCESS_DATE), B.NAME, B.LOCATION
Data Sample:
Table 1: Errors
Table 2: Success
Table 3: Details
Expected Results :
Website_Class_ID
Website_ID
Date of Error or Success
Count of Errors
Count of Success
Website Name
Website Location
ClassB
ID 2
12/1/2019
3
5
Website #1
USA
ClassC
ID 3
12/2/2019
1
6
Website #2
Canada
SELECT
`Errors$`.WEBSITE_CLASS_ID
,`Errors$`.WEBSITE_ID
,`Errors$`.ERROR_DATE
,COUNT(`Errors$`.EVENT_NAME)
,`Details$`.NAME
,`Details$`.LOCATION
FROM
`D:\mike\SnapCommerce Case Study\Data.xlsx`.`Errors$` `Errors$`,
INNER JOIN `D:\mike\SnapCommerce Case Study\Data.xlsx`.`Details$`
`Details$`
ON `Details$`.WEBSITE_ID = `Errors$`.WEBSITE_ID
GROUP BY `Errors$`.WEBSITE_CLASS_ID, `Errors$`.WEBSITE_ID,
`Errors$`.ERROR_DATE, `Details$`.NAME, `Details$`.LOCATION
UNION
SELECT
`Success$`.WEBSITE_CLASS_ID
,`Success$`.WEBSITE_ID
,DATE(`Success$`.SUCCESS_DATE)
,COUNT(`Success$`.SUCCESS)
,`Details$`.NAME
,`Details$`.LOCATION
FROM
`D:\mike\SnapCommerce Case Study\Data.xlsx`.`Success$` `Success$`,
INNER JOIN `D:\mike\SnapCommerce Case Study\Data.xlsx`.`Details$`
`Details$`
ON `Details$`.WEBSITE_ID = `Success$`.WEBSITE_ID
GROUP BY `Success$`.WEBSITE_CLASS_ID, `Success$`.WEBSITE_ID,
`Success$`.SUCCESS_DATE, `Details$`.NAME, `Details$`.LOCATION
Vertically, You can use UNION, this would eliminate doubles as well.
If you need them use UNION ALL
SELECT
A.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,A.WEBSITE_ID AS WEBSITE_ID
,A.ERROR_DATE AS DATE_OF_ERROR
,COUNT(A.EVENT_NAME) AS NUMBER_OF_ERRORS
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..ERRORS A
INNER JOIN &DATABASE..DETAILS B
ON A.WEBSITE_ID = B.WEBSITE_ID
GROUP BY A.WEBSITE_CLASS_ID, A.WEBSITE_ID, A.ERROR_DATE, B.NAME, B.LOCATION
UNION
SELECT
C.WEBSITE_CLASS_ID AS WEBSITE_CLASS_ID
,C.WEBSITE_ID AS WEBSITE_ID
,DATE(C.SUCCESS_DATE) AS SUCCESSFUL_CONNECTION
,COUNT(C.SUCCESS) AS COUNT_SUCCESS_CNCTN
,B.NAME AS WEBSITE_NAME
,B.LOCATION AS COMPANY_LOCATION
FROM
&DATABASE..SUCCESS C
INNER JOIN
&DATABASE..DETAILS B
ON C.WEBSITE_ID = B.WEBSITE_ID
GROUP BY C.WEBSITE_CLASS_ID, C.WEBSITE_ID, DATE(C.SUCCESS_DATE), B.NAME, B.LOCATION

select records as a single with different queries

I have a table, the table structure of which is as follows
id service_type pincode
---------------------------------
1 B 695582
2 D 676102
3 P 685584
4 B 685608
I will get two different pincodes from the front end. say for example 695582 and 685608. I need to get the service_types at these pincodes with single query and the results should be a single row. I have tried a UNION query, but the results are in two different row.
select 'buyer' name, service_type from tm_location_carrier_lnk where pincode=695582
UNION
select 'seller' name, service_type from tm_location_carrier_lnk where pincode=685608
The result of the above query is as follows
name service_type
------------------
buyer B
seller B
How can i get results in a single row as follows
Buyer Seller
B B
Why not doing
SELECT (select service_type from tm_location_carrier_lnk where pincode=695582 LIMIT 1) as Buyer, (select service_type from tm_location_carrier_lnk where pincode=685608 LIMIT 1) as Seller;
Here you can find a working example: http://sqlfiddle.com/#!9/e01426/1
edit: added LIMIT 1 for avoiding duplicated pincodes.
One solution assuming unique pincodes and specific to your request:
Select
(select max(service_type)
from tm_location_carrier_lnk
where pincode=695582) as Buyer
, (select max(service_type)
from tm_location_carrier_lnk
where pincode=685608) as Seller;

SQL statement to get similar records inside lookup table

I have a table in mysql of hashtags:
strHash | nPersonID
-------------------------
#dogowner | 1
#catowner | 1
#dogowner | 2
#mouseowner | 3
#fish | 3
#vancouver | 1
#vancouver | 3
I'd like to query the table with a MySQL statement and say, I want nPersonID = 1, return a result of all people that share one ore more strHash values.
This will allow me to show similar people when viewing a specific person. (or, people who share similar hash tags - some but not necessarily all)
The simplest way to get just a list of people that share hastags with person 1 is this:
SELECT DISTINCT nPersonID
FROM table
WHERE strHash IN (
SELECT b.strHash
FROM table b
WHERE b.nPersonID=1
)
But you can get some little bit of extra info without making things too complex.
For example, this query will list the same people, but also give you a quantifier of how similar these people's hashtags are to those person 1:
SELECT nPersonID, COUNT(DISTINCT strHash) AS shared_hashtags
FROM table
WHERE strHash IN (
SELECT b.strHash
FROM table b
WHERE b.nPersonID=1
)
GROUP BY nPersonID
ORDER BY shared_hashtags DESC
This will select all the people that have one or more of the hashtags that person 1 has... including person 1.
The resuling list will be ordered by the number of common hastags... with the most similar people on top (including person 1).
Try this SQL:
SELECT DISTINCT t2.nPersonID
FROM table t1
JOIN table t2
ON t1.strHash = t2.strHash
WHERE t1.nPersonID = 1
The idea:
Get the hashtags of the selected person
Get all persons which have similar hashtags
Count how many hastags are matching
The query:
SELECT
S.nPersonId
, COUNT(1) AS SimilarHashCount
FROM (
SELECT
strHash
FROM
hashtags
WHERE
nNersonID = 1
) P
INNER JOIN (
SELECT
strHash
, nPersonD
FROM
hashtags
WHERE
nNersonID != 1
) S
ON P.strHash = S.strHash
GROUP BY
S.nPersonID
ORDER BY
COUNT(1) DESC
You can limit the result, or you can use the HAVING statement to filter the results
Many ways to achieve this. I'll do it with following query
SELECT DISTINCT [nPersonID]
FROM [htag]
where strHash in (select strHash FROM [htag] where [nPersonID] = 1)
This will output as below
nPersonID
1
2
3
If you wish to get result without the ID '1' (request id) add another condition
SELECT DISTINCT [nPersonID]
FROM [htag]
where strHash in (select strHash FROM [htag] where [nPersonID] = 1)
and [nPersonID] != 1
Output:
nPersonID
2
3
Hope this helps!
SELECT *, COUNT(*) FROM XXX GROUP BY strHash HAVING COUNT(*) > 1
This question has been asked before - How to select non "unique" rows
The answer above belongs to judda (a bit modified)

Count occurency of SQL query results

I have a MySQL database with a table called "orders" containing all my orders. In this table I have different fields like:
id
userId
dateOrder
I would like to get ALL the orders grouped by users ONLY for users who did between 2 and 5 orders.
But my SQL queries don't work. Considering theses entries:
id userId dateOrder
1 138 2013-03-19
2 138 2013-03-19
3 222 2013-03-19
I would like a SQL request that only select orders who have been made by users who did at least 2 orders.
For this example, the SQL should return :
userId 138
I tried with GROUP BY, with DISTINCT, but none of these works. Can you help me please ?
Thanks !!
You should be able to use a HAVING clause to get the result:
select userid
from orders
group by userid
having COUNT(*) >= 2
and COUNT(*) <= 5
See SQL Fiddle with Demo
If you then want to return all of the details about each order, you can expand the query to:
select o1.id, o1.userid, o1.dateorder
from orders o1
where exists (select userid
from orders o2
where o1.userid = o2.userid
group by userid
having COUNT(*) >= 2
and COUNT(*) <= 5)
See SQL Fiddle with Demo
I think this should do it...
Select * from orders where userid in
(
Select userid from orders
group by userid having count(1) between 2 and 5
)

Getting total count and conditional count in a single query

I have a table called apps in MYSQL database.
id
source
1
fb
2
gd
3
tw
4
fb
5
qu
6
fb
I want a single query that will give me total count along with fb count
totalcount
source
6
3
To count for fb in the table try this: (using SUM)
SELECT COUNT(*) totalcount,
SUM(source='fb') source
FROM table1
Another way to do the same: (using COUNT)
SELECT COUNT(*) totalcount,
COUNT(CASE WHEN source = 'fb' THEN 0 END) source
FROM table1;
To count all source in the table try this:
SELECT COUNT(id) totalcount,
COUNT(DISTINCT source) source
FROM table1
See this SQLFiddle
select sum(source='fb') as fb_count,
count(*) as totalcount
from your_table
SQLFiddle