MS SQL Server select statement: display all combinations from two tables - sql-server

I have two tables in a MS SQL Server database:
Table1
Emp_ID, First_Name, Last_Name
1 Joe Smith
2 Bob Jones
Table2
Emp_ID, Dept_ID, Status
1 1 Active
1 2 NotActive
1 3 NotActive
2 1 Active
What I would like to do is create a SQL select statement that displays a row for every employee and department combination along with the status even if the employee has never been in the department (table 2). For the sample data, this should bring back 6 records since there are 2 employees and 3 departments.
Any help would be appreciated!
Thank you

If you don't have a departments table, you'll need to create a subquery to get the distinct list of dept_ids to cross join on:
select emp_id, first_name, last_name, dept.dept_id, status
from empl
cross join (select distinct dept_id from empdept) dept
left join empdept on empl.emp_id = empdept.empt_id
and dept.dept_id = empdept.dept_id
SQL Fiddle Demo

SELECT *
FROM table1 T1 FULL OUTER JOIN table2 T2
ON T1.EMP_ID=T2.EMP_ID

Related

Removing Duplicate Values within Group By

I am using SQL-Server 2012 in Microsoft Visual Studio 2010.
As a preface, I cannot use ROW_NUMBER() OVER(PARTITION BY Col) as the OVER() method is not supported by the Visual Studio Version I am using. I am not in a place, unfortunately, where I can get new software.
I have a group of department and job IDs such that:
SELECT
Department,
Job_ID
FROM
Table1
JOIN Table2 on
Table1.id = Table2.id
Department Job_ID
__________________________
Marketing J3
Engineering J1
Marketing J2
Recruiting J2
Marketing J8
Administration J3
Recruiting J1
Administration J5
Administration J1
I am trying to group by Job_ID, show the distinct Departments associated with each Job_ID, and only include groups that have more than 2 departments. The end results would be:
Department Job_ID
__________________________
Administration J1
Recruiting J1
Engineering J1
Marketing J2
Recruiting J2
Marketing J3
Administration J3
I have tried:
SELECT Job_ID, count(distinct(Department)) as Dept_CountD
FROM Table1 JOIN Table2 on Table1.id=Table2.id
GROUP BY Job_ID
HAVING count(distinct(Department)) >1
This works, however, it does not group the departments along with each ID. I also know (and have tested) that I cannot insert Department into the Group By statement, as that would return distinct department counts only equal to 1!
I have tried building the above statement into a CTE and inner joining on the Job_ID so I only have Job_IDs that have more than 2 distinct departments associated with them, however, I end up with duplicate Departments in the grouping from the join.
I'm thinking perhaps joining to a sub query or doing a semi join?
How about this:
SELECT
Department,
Job_ID
FROM Table1
JOIN Table2 on Table1.id = Table2.id
WHERE Job_ID IN (SELECT Job_ID
FROM Table1 JOIN Table2 on Table1.id=Table2.id
GROUP BY Job_ID
HAVING count(distinct(Department)) >1)
Use COUNT() Over() window aggregate
select * from
(
select count(1)over(partition by Job_ID) as cnt,*
From <<join>>
) A
Where cnt > 1
try this: ( I am only guessing which table has the Departments and which has the Jobs cause you did not provide schema.
SELECT Job_ID, count(*) Dept_CountD
FROM Table1 a JOIN Table2 b on a.id=b.id
where (Select count(*) from table1
Where JobId = a.JobId) > 1

Selecting count of exist rows in other table and join it to our SQL server table

I have two tables in SQL server. first one is table of customers info and second includes all purchases,
At first Table i have id of our customers, and the purchases table although has the id of who bought that product. so how can i select all customers table that include how many time they purchased products?
i tried this
SELECT TOP 2000 COUNT(tblpurchase.id) as id2,tblcustomers.* From tblpurchase
right join on tblpurchase.id=tblcustomers.id
but didn't word. how can i solve this?
Use OUTER APPLY
SELECT TOP 2000 tblcustomers.* ,M.CustomerCount
From tblcustomers
OUTER APPLY(
SELECT COUNT(*) as CustomerCount
from tblpurchase
WHERE tblpurchase.CustomerIDColumn = tblcustomers.id
)M
Here tblpurchase.CustomerIDColumn use actual name of customerID column
Also you can with LEFT JOIN
SELECT TOP 2000
C.*,
P.CustomerCount
From
tblcustomers C LEFT JOIN
(
SELECT
TP.CustomerId,
COUNT(*) as CustomerCount
FROM
tblpurchase TP
GROUP BY
TP.CustomerId
) P ON C.Id = P.CustomerId

Query to data from two tables having same column but having different data

I have two tables one is Registration which has column as reg_id and first_name and other details
and the other table is activity which also has reg_id ,first_name and other details with reg_id as common the tables. There can be multiple entries for 1 reg_id in activity table
I want to have query these two tables in such a way ,I want to know all those reg_id which have different first_name in both the tables.
Eg :if
1st table data
--------------
Reg_id first_name
1 ashu
2 &parker
3 *fzz
4 john
2nd Table data
--------------
Reg_id first_name
1 ashu
2 parker
3 michel
4 john
The output of my query should return 2,3 reg_ids
select table1.reg_id from table1
inner join table2 on table1.reg_id = table2.reg_id
where table1.first_name <> table2.first_name
select the one reg id, joing the tables on the reg id value.
where the two first name fields don't equal each other
SQL is not case sensitive either.
Like this......
SELECT t1.reg_id
FROM table1 t1
INNER JOIN table2 t2 ON t1.reg_id = t2.reg_id
WHERE t1.first_name <> t2.first_name
Here is a good link to help you understand SQL Joins : http://www.w3schools.com/sql/sql_join.asp

T-SQL Join Query

I have been trying to write a query for a view but I can't seem to get it... I have two tables that I need to join... but what I need is that for every ID in table 1 I get all records on table 2. For Example:
Table 1 Table 2
Jhon Car
Bill House
Jet
I would like to get:
Table 3
Jhon Car
Jhon House
Jhon Jet
Bill Car
Bill House
Bill Jet
P.S. Data on both tables can vary.
P.S.S. Table 1 is actually a Left Outer Join between two other tables where the first table contains the indexes and the second contains the field used to create relation to Table 2.
You need a CROSS JOIN for this (AKA Cartesian Product).
SELECT t1.col, t2.col
FROM Table1 t1 cross join Table2 t2
Try this
select * from table1, table2
or use a CROSS JOIN if database supports it
SELECT *
FROM table1
CROSS JOIN
table2
select columns you want to get
from Table1 Cross Join Table2

Combine two tables that have no common fields

I want to learn how to combine two db tables which have no fields in common. I've checked UNION but MSDN says :
The following are basic rules for combining the result sets of two queries by using UNION:
The number and the order of the columns must be the same in all queries.
The data types must be compatible.
But I have no fields in common at all. All I want is to combine them in one table like a view.
So what should I do?
There are a number of ways to do this, depending on what you really want. With no common columns, you need to decide whether you want to introduce a common column or get the product.
Let's say you have the two tables:
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
Forget the actual columns since you'd most likely have a customer/order/part relationship in this case; I've just used those columns to illustrate the ways to do it.
A cartesian product will match every row in the first table with every row in the second:
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
That's probably not what you want since 1000 parts and 100 customers would result in 100,000 rows with lots of duplicated information.
Alternatively, you can use a union to just output the data, though not side-by-side (you'll need to make sure column types are compatible between the two selects, either by making the table columns compatible or coercing them in the select):
> select id as pid, desc, null as cid, null as name from parts
union
select null as pid, null as desc, id as cid, name from custs;
pid desc cid name
--- ---- --- ----
101 Bob
102 Paul
1 Sprocket
2 Flange
In some databases, you can use a rowid/rownum column or pseudo-column to match records side-by-side, such as:
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
The code would be something like:
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
It's still like a cartesian product but the where clause limits how the rows are combined to form the results (so not a cartesian product at all, really).
I haven't tested that SQL for this since it's one of the limitations of my DBMS of choice, and rightly so, I don't believe it's ever needed in a properly thought-out schema. Since SQL doesn't guarantee the order in which it produces data, the matching can change every time you do the query unless you have a specific relationship or order by clause.
I think the ideal thing to do would be to add a column to both tables specifying what the relationship is. If there's no real relationship, then you probably have no business in trying to put them side-by-side with SQL.
If you just want them displayed side-by-side in a report or on a web page (two examples), the right tool to do that is whatever generates your report or web page, coupled with two independent SQL queries to get the two unrelated tables. For example, a two-column grid in BIRT (or Crystal or Jasper) each with a separate data table, or a HTML two column table (or CSS) each with a separate data table.
This is a very strange request, and almost certainly something you'd never want to do in a real-world application, but from a purely academic standpoint it's an interesting challenge. With SQL Server 2005 you could use common table expressions and the row_number() functions and join on that:
with OrderedFoos as (
select row_number() over (order by FooName) RowNum, *
from Foos (nolock)
),
OrderedBars as (
select row_number() over (order by BarName) RowNum, *
from Bars (nolock)
)
select *
from OrderedFoos f
full outer join OrderedBars u on u.RowNum = f.RowNum
This works, but it's supremely silly and I offer it only as a "community wiki" answer because I really wouldn't recommend it.
SELECT *
FROM table1, table2
This will join every row in table1 with table2 (the Cartesian product) returning all columns.
select
status_id,
status,
null as path,
null as Description
from
zmw_t_status
union
select
null,
null,
path as cid,
Description from zmw_t_path;
try:
select * from table 1 left join table2 as t on 1 = 1;
This will bring all the columns from both the table.
If the tables have no common fields then there is no way to combine the data in any meaningful view. You would more likely end up with a view that contains duplicated data from both tables.
To get a meaningful/useful view of the two tables, you normally need to determine an identifying field from each table that can then be used in the ON clause in a JOIN.
THen in your view:
SELECT T1.*, T2.* FROM T1 JOIN T2 ON T1.IDFIELD1 = T2.IDFIELD2
You mention no fields are "common", but although the identifying fields may not have the same name or even be the same data type, you could use the convert / cast functions to join them in some way.
why don't you use simple approach
SELECT distinct *
FROM
SUPPLIER full join
CUSTOMER on (
CUSTOMER.OID = SUPPLIER.OID
)
It gives you all columns from both tables and returns all records from customer and supplier if Customer has 3 records and supplier has 2 then supplier'll show NULL in all columns
Select
DISTINCT t1.col,t2col
From table1 t1, table2 t2
OR
Select
DISTINCT t1.col,t2col
From table1 t1
cross JOIN table2 t2
if its hug data , its take long time ..
SELECT t1.col table1col, t2.col table2col
FROM table1 t1
JOIN table2 t2 on t1.table1Id = x and t2.table2Id = y
Joining Non-Related Tables
Demo SQL Script
IF OBJECT_ID('Tempdb..#T1') IS NOT NULL DROP TABLE #T1;
CREATE TABLE #T1 (T1_Name VARCHAR(75));
INSERT INTO #T1 (T1_Name) VALUES ('Animal'),('Bat'),('Cat'),('Duet');
SELECT * FROM #T1;
IF OBJECT_ID('Tempdb..#T2') IS NOT NULL DROP TABLE #T2;
CREATE TABLE #T2 (T2_Class VARCHAR(10));
INSERT INTO #T2 (T2_Class) VALUES ('Z'),('T'),('H');
SELECT * FROM #T2;
To Join Non-Related Tables , we are going to introduce one common joining column of Serial Numbers like below.
SQL Script
SELECT T1.T1_Name,ISNULL(T2.T2_Class,'') AS T2_Class FROM
( SELECT T1_Name,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS S_NO FROM #T1) T1
LEFT JOIN
( SELECT T2_Class,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS S_NO FROM #T2) T2
ON t1.S_NO=T2.S_NO;
select * from this_table;
select distinct person from this_table
union select address as location from that_table
drop wrong_table from this_database;
Very hard when you have to do this with three select statments
I tried all proposed techniques up there but it's in-vain
Please see below script. please advice if you have alternative solution
select distinct x.best_Achiver_ever,y.Today_best_Achiver ,z.Most_Violator from
(SELECT Top(4) ROW_NUMBER() over (order by tl.username) AS conj, tl.
[username] + '-->' + str(count(*)) as best_Achiver_ever
FROM[TiketFollowup].[dbo].N_FCR_Tikect_Log_Archive tl
group by tl.username
order by count(*) desc) x
left outer join
(SELECT
Top(4) ROW_NUMBER() over (order by tl.username) as conj, tl.[username] + '-->' + str(count(*)) as Today_best_Achiver
FROM[TiketFollowup].[dbo].[N_FCR_Tikect_Log] tl
where convert(date, tl.stamp, 121) = convert(date,GETDATE(),121)
group by tl.username
order by count(*) desc) y
on x.conj=y.conj
left outer join
(
select ROW_NUMBER() over (order by count(*)) as conj,username+ '--> ' + str( count(dbo.IsViolated(stamp))) as Most_Violator from N_FCR_Ticket
where dbo.IsViolated(stamp) = 'violated' and convert(date,stamp, 121) < convert(date,GETDATE(),121)
group by username
order by count(*) desc) z
on x.conj = z.conj
Please try this query:
Combine two tables that have no common columns:
SELECT *
FROM table1
UNION
SELECT *
FROM table2
ORDER BY orderby ASC

Resources