I have a very simple database. It contains 3 tables. The first is the primary input table where values go in. The 2nd and 3rd are there purely for translating values to names for a view. When I view the rows in table 1, I can see that column businessUnit contains valid values in all rows. When I add the Business_Units table (The 3rd table in this DB), all but 2 rows go away and despite the businessUnit value both being 1 in the 1st table, the view gives them different names.
I created a DB diagram and uploaded a screenshot to imgur. Link: http://imgur.com/jXF7L1R
I only have 2 relationships in the table. One from equipType on New_Equipment_User to id in Equipment_Type and one from businessUnit in New_Equipment_User to id in Business_Units. The weird thing is that the Equipment Type works perfectly, yet when I replicate the table, relationship and view information exactly, it doesn't work. Instead of 6 rows appearing, there are only 2 which share the same value in businessUnit, but gives 2 different names for it.
In case it matters, here is my view Query:
SELECT dbo.New_Equipment_User.id, dbo.Equipment_Type.name AS equipType, dbo.New_Equipment_User.jobNumber, dbo.New_Equipment_User.costCode,
dbo.New_Equipment_User.reason, dbo.New_Equipment_User.mobile, dbo.New_Equipment_User.mobileQty, dbo.New_Equipment_User.mobileComment,
dbo.New_Equipment_User.laptop, dbo.New_Equipment_User.laptopQty, dbo.New_Equipment_User.laptopComment, dbo.New_Equipment_User.desktop,
dbo.New_Equipment_User.desktopQty, dbo.New_Equipment_User.desktopComment, dbo.New_Equipment_User.modem, dbo.New_Equipment_User.modemQty,
dbo.New_Equipment_User.modemComment, dbo.New_Equipment_User.printer, dbo.New_Equipment_User.printerQty, dbo.New_Equipment_User.printerComment,
dbo.New_Equipment_User.camera, dbo.New_Equipment_User.cameraQty, dbo.New_Equipment_User.cameraComment, dbo.New_Equipment_User.dateRequired,
dbo.New_Equipment_User.requestedBy, dbo.New_Equipment_User.dateRequested, dbo.New_Equipment_User.approvalStatus,
dbo.Business_Units.name AS businessUnit
FROM dbo.New_Equipment_User
JOIN dbo.Equipment_Type ON dbo.New_Equipment_User.equipType = dbo.Equipment_Type.id
JOIN dbo.Business_Units ON dbo.New_Equipment_User.id = dbo.Business_Units.id
WHERE (dbo.New_Equipment_User.approvalStatus = '0')
And here is an image of the view since it is easier to read: http://imgur.com/pZ97ehQ
Is anyone able to assist with why this might be happening?
Try using a LEFT JOIN
SELECT ...
FROM dbo.New_Equipment_User
JOIN dbo.Equipment_Type ON dbo.New_Equipment_User.equipType = dbo.Equipment_Type.id
LEFT JOIN dbo.Business_Units ON dbo.New_Equipment_User.id = dbo.Business_Units.id
This will ensure that all dbo.New_Equipment_User and all dbo.Equipment_Type is present
Related
I have a table where I have ranked all the rows based on the created date column and have the rank indicated on the table as below
main table
I would like to create a cross-reference table with the golden record as the recurring column and the other two records as associated records as below.
output desired
I would like to know how I can achieve this using SQL.
I have tried creating a seperate table with all ID numbers (Rank = 1) and then joining it with the main table to get the ones with rank 1,2 and 3 associated with it. But it doesnt seem to work as I intend to.
output
I have not tested but something like this should work. You might want to add a name_id field.
select b.id_number,a.id_number
from table a
join table b on a.name=b.name
where b.rank=1
I created a view in SQL Server that includes a row_number() function. The table referenced in the view contains every record in my database and enumerates records based on duplicate instances of a composite ID. For example:
row_number() over (
partition by
composite_id
order by
sample_value) as rownum
The issue is that whenever I join this view against another table (or filter rows based on a WHERE clause), the row number nevertheless always returns the value that would be returned for the full table referenced in the view. Instead, I'd like the row number to update depending on the records that are ultimately returned in the eventual result set.
For example:
select *
from my_created_view a
where a.sample_value in ('a','b','c')
or
select *
from my_created_view a
inner join subset_of_data b on a.sample_value = b.sample_value
...where either query above would result in a smaller number of records than are contained in the full original table and the resulting set of composite_id would sometimes contain only one instance. In cases where the result set contains only one instance of composite_id, I'd like that row to receive a value of 1.
Is this possible? Or does row numbering within a view create a row number that's tied only to the query within the created view?
Thanks in advance for any light you can shed here!
I have 3 (hypothetical) tables.
Photos (a list of photos)
Attributes (things describing the photos)
PhotosToAttributes (a table to link the first 2)
I want to retrieve the Names of all the Photos that have a list of attributes.
For example, all photos that have both dark lighting and are portraits (AttributeID 1 and 2). Or, for example, all photos that have dark lighting, are portraits and were taken at a wedding (AttributeID 1 and 2 and 5). Or any arbitrary number of attributes.
The scale of the database will be maybe 10,000 rows in Photos, 100 Rows in Attributes and 100,000 rows in PhotosToAttributes.
This question: SQL: Many-To-Many table AND query is very close. (I think.) I also read the linked answers about performance. That leads to something like the following. But, how do I get Name instead of PhotoID? And presumably my code (C#) will build this query and adjust the attribute list and count as necessary?
SELECT PhotoID
FROM PhotosToAttributes
WHERE AttributeID IN (1, 2, 5)
GROUP by PhotoID
HAVING COUNT(1) = 3
I'm a bit database illiterate (it's been 20 years since I took a database class); I'm not even sure this is a good way to structure the tables. I wanted to be able to add new attributes and photos at will without changing the data access code.
It is probably a reasonable way to structure the database. An alternate would be to keep all the attributes as a delimited list in a varchar field, but that would lead to performance issues as you search the field.
Your code is close, to take it to the final step you should just join the other two tables like this:
Select p.Name, p.PhotoID
From Photos As p
Join PhotosToAttributes As pta On p.PhotoID = pta.PhotoID
Join Attributes As a On pta.AttributeID = a.AttributeID
Where a.Name In ('Dark Light', 'Portrait', 'Wedding')
Group By p.Name, p.PhotoID
Having Count(*) = 3;
By joining the Attributes table like that it means you can search for attributes by their name, instead of their ID.
For first create view from your joins:
create view vw_PhotosWithAttributes
as
select
p.PhotoId,
a.AttributeID,
p.Name PhotoName,
a.Name AttributeName
from Photos p
inner join PhotosToAttributes pa on p.PhotoId = pa.PhotoId
inner join Attributes a on a.AttributeID = pa.AttributeID
You can easy ask for attribute, name, id but don't forget to properly index field.
*EDIT** Thanks for all the input, and sorry for late reply. I have been away during the weekend without access to internet. I realized from the answers that I needed to provide more information, so people could understand the problem more throughly so here it comes:
I am migrating an old database design to a new design. The old one is a mess and very confusing ( I haven't been involved in the old design ). I've attached a picture of the relevent part of the old design below:
The table called Item will exist in the new design as well, and it got all columns that I need in the new design as well except one and it is here my problem begin. I need the column which I named 'neededProp' to be associated( with associated I mean like a column in the new Item table in the new design) with each new migrated row from Item.
So for a particular eid in table Environment there can be n entries in table Item. The "corresponding" set exists in table Room. The only way to know which rows that are associated in Item and Room are with the help of the columns "itemId" and "objectId" in the respective table. So for example for a particular eid there might be 100 entries in Item and Room and their "itemId" and "objectId" can be values from 1 to 100, so that column is only unique for a particular eid ( or baseSeq which it is called in table BaseFile).
Basically you can say that the tables Environment and BaseFile reminds of each other and the tables Item and Room reminds of each other. The difference is that some tables lack some columns and other may have some extra. I have no idea why it is designed like this from the beginning.
My question is if someone can help me with creating a query so that I can be able to find out the proper "neededProp" for each row in the Item-table so I can get that data into the new design?
*OLD-PART**This might be a trivial question but I can't get it to work as I want. I want to join a few tables as in the sql-statement below. If I start like this and run this query
select * from Environment e
join items ei on e.eid = ei.eid
I get like 400000 rows which is what I want. However if I add one more line so it looks like this:
select * from Environment e
join items ei on e.eid= ei.eid
left join Room r on e.roomnr = r.roomobjectnr
I get an insane amount of rows so there must be some multiplication going on. I want to get the same amount of rows ( like 400000 in this case ) even after joining the third table. Is that possible somehow? Maybe like creating a temporary view with the first 2 rows.
I am using MSSQL server.
So without knowing what data you have in your second query it's very difficult to say exactly how to write this out, and you're likely having a problem where there's an additional column that you are joining to in Rooms that perhaps you have forgotten such as something indicating a facility or hallway perhaps where you have multiple 'Room 1' entries as an example.
However, to answer your question regarding another way to write this out without using a temp table I've crufted up the below as an example of using a common table expression which will only return one record per source row.
;WITH cte_EnvironmentItems AS (
SELECT *
FROM Environment E
INNER JOIN Items I ON I.eid = E.eid
), cte_RankedRoom AS (
SELECT *
,ROW_NUMBER() OVER (ORDER BY R.UpdateDate DESC) [RN]
FROM Room R
)
SELECT *
FROM cte_EnvironmentItems E
LEFT JOIN cte_RankedRoom R ON E.roomnr = R.roomobjectnr
AND R.RN = 1
btw,do you want column from room table.if no then
select * from Environment e
join items ei on e.eid= ei.eid
where e.roomnr in (select r.roomobjectnr from Room r )
else
select * from Environment e
join items ei on e.eid= ei.eid
left join (select distinct roomobjectnr from Room) r on e.roomnr = r.roomobjectnr
I'm trying to implement a feature whereby, apart from all the reports that I have in my system, I will allow the end user to create simple reports. (not overly complex reports that involves slicing and dicing across multiple tables with lots of logic)
The user will be able to:
1) Select a base table from a list of allowable tables (e.g., Customers)
2) Select multiple sub tables (e.g., Address table, with AddressId as the field to link Customers to Address)
3) Select the fields from the tables
4) Have basic sorting
Here's the database schema I have current, and I'm quite certain it's far from perfect, so I'm wondering what else I can improve on
AllowableTables table
This table will contain the list of tables that the user can create their custom reports against.
Id Table
----------------------------------
1 Customers
2 Address
3 Orders
4 Products
ReportTemplates table
Id Name MainTable
------------------------------------------------------------------
1 Customer Report #2 Customers
2 Customer Report #3 Customers
ReportTemplateSettings table
Id TemplateId TableName FieldName ColumnHeader ColumnWidth Sequence
-------------------------------------------------------------------------------
1 1 Customer Id Customer S/N 100 1
2 1 Customer Name Full Name 100 2
3 1 Address Address1 Address 1 100 3
I know this isn't complete, but this is what I've come up with so far. Does anyone have any links to a reference design, or have any inputs as to how I can improve this?
This needs a lot of work even though it’s relatively simple task. Here are several other columns you might want to include as well as some other details to take care of.
Store table name along with schema name or store schema name in additional column, add column for sorting and sort order
Create additional table to store child tables that will be used in the report (report id, schema name, table name, column in child table used to join tables, column in parent table used to join tables, join operator (may not be needed if it always =)
Create additional table that will store column names (report id, schema name, table name, column name, display as)
There are probably several more things that will come up after you complete this but hopefully this will get you in the right direction.