Combobox with Column Values based on Field Value - sql

I'm making a combobox, that shows a key identifier, and the summary.
.
So I've got cases where there's an Epic (2), and a Story (3), with the same Parent ID. I've also got cases where there's a story (5) with a parent ID (4), that isn't in the table.
I want to create a two column combobox that looks like this
.
I want the first column, my bound column, to only show each Parent ID once. In cases like Parent ID 2, where there is both an Epic and a Story, I want the second column to show the Summary of the Epic. But in cases of Parent ID 4, where ID 4 doesn't exist on my table as it's own record, I want to have Summary populate with the summary of ID 5.
I'm totally lost on how to do this in SQL.
SELECT table.[Parent ID], First(table.[Summary]) As [Summary]
is about as far as I've gotten, but that just returns the first Summary for a given Parent ID, whether that record is Type Epic or Story.
I've been stumped on this for a while, any help is most appreciated.

Consider:
SELECT ParentID, Summary FROM Table3 WHERE ID IN (
SELECT TOP 1 ID FROM Table3 AS Dupe
WHERE Dupe.ParentID=Table3.ParentID ORDER BY Dupe.Type);

This is where GROUP BY comes into effect.
SELECT ParentID, MAX(Summary)
FROM Table3
GROUP BY ParentID
But that is only part of the picture, because you will lose the 'Once Told Me', as it's alphabetically less than 'The World'.
If you need to see all Summary then this may help:
SELECT ParentID, Summary, MAX(Type) AS [Type], COUNT(*)
FROM Table3
GROUP BY ParentID, Summary

Hmmm, I think the following does what you want by prioritizing the Epic:
select parentid,
nz(max(iif(type = "Epic", summary, null)),
max(summary)
)
from t
group by parentid;

Related

How to get particular name from logs

I have code where I am getting case details. Now I need to get LogAgent name for the case.
But it is in the activity log table which have the columns CreatedBy, Type and this table has multiple rows (Logs).
Created by has different agent names and type has different values like LogComment.
I need to get first LogComment from the Type column and corresponding created by name.
Could any one please help how to do?
Below is my data and I need to get highlighted row
Sample Data
If you just want the first Comment for a particular user
Select Top 1 *
From YourTable
Where [Type]='Log Comment'
and [CreatedBy] = 'Benn'
Order By yourdatetimecolumn
If you want the 1st Comment for each User
Select Top 1 with ties *
From YourTable
Where [Type]='Log Comment'
Order By row_number() over (partition by CreatedBy order by yourdatetimecolumn)
Just an aside: Best to post sample data and desired results as text.

SQL Server CE retrieve a field from the record with the MAX(Id)

I am using SQL Server Compact 4.0 and am trying to get one query to return a single record with a column Alarm based on the maximum identity when another column Cleared is NULL.
This works:
SELECT Id, Alarm
FROM Alarm_History
WHERE Cleared IS NULL
Giving me half the answer. The problem is that it returns several records.
This also works:
SELECT MAX(Id)
FROM Alarm_History
WHERE Cleared IS NULL
And it gives me the other half of the answer, but I can't get the value "Alarm" that I am looking for.
But they DON'T work together as in:
SELECT Id, Alarm
FROM Alarm_History
WHERE Cleared IS NULL AND Id = MAX(Id)
OR
SELECT MAX(Id), Alarm
FROM Alarm_History
WHERE Cleared IS NULL
With the queries above I can do two consecutive queries to get the result back, but I don't think this is very efficient. Is there a way to do this in one trip to the database?
Thanks
Jeff
You could do it with max and a join, but that would be far too complicated. Instead, you can just try:
SELECT TOP 1 Id, Alarm
FROM Alarm_History
WHERE Cleared IS NULL
ORDER BY Id DESC
Note: what happens if two alarms have max id ? Well, that shouldn't happen (Id is unique). But that's an interesting problem nevertheless (suppose the field is not Id but Price, and you want all alarms with max price, and you don't know how many there'll be, so you cannot use TOP 1 anymore).
You'll have to use a CROSS JOIN;
SELECT Id, Price
FROM Alarms
JOIN (SELECT MAX(Price) as maxPrice FROM Alarms) b
WHERE Alarms.Price = b.maxPrice
Don't think "max". Think "order by". Try this:
SELECT TOP 1 Id, Alarm
FROM Alarm_History
WHERE Cleared IS NULL
ORDER BY Id DESC;
That way, you can get all the fields you want associated with the max id.
Try,
SELECT Id, Alarm FROM Alarm_History WHERE ID in (SELECT MAX(Id) FROM Alarm_History WHERE Cleared IS NULL)

SSRS Recursive Parent gives distinct children only, when children have multiple parents

I have made an SSRS report using the recursive parent functionality to show a hierarchical tree of values. The problem I have is that some children have more than one parent, but because (in order to use the recursive parent nicely) I need to group the results by Id, I only see distinct entries. This means that I only see each child once, even if it "should" appear in multiple locations in the report (under each of its parents).
Here is an example dataset that shows what I mean:
DECLARE #Bear Table
( ParentId INT NOT NULL
,Id INT NOT NULL
,Name VARCHAR(255))
INSERT INTO #Bear
SELECT * FROM
(SELECT 0 AS ParentId, 1 AS Id, 'Daddy Bear' AS Name UNION
SELECT 0 AS ParentId, 2 AS Id, 'Mummy Bear' AS Name UNION
SELECT 1 AS ParentId, 3 AS Id, 'Baby Bear' AS Name UNION
SELECT 2 AS ParentId, 3 AS Id, 'Baby Bear' AS Name) AS FamilyMember
ORDER BY FamilyMember.Id
SELECT * FROM #Bear
My Actual data contains lots of "Baby Bears" where for instance a function is used by more than one procedure, or a procedure is used by more than one report.
When I make the report, I group on Bear.Id, with a recursive parent of Bear.ParentId, which gives me something like this (in the report table):
Level 1 Level 2
Daddy Bear
Baby Bear
Mummy Bear
As you can see, "Baby Bear" only appears once (normally, Id would be unique and this would make perfect sense). What I would like is for SSRS to display is something more like this:
Level 1 Level 2
Daddy Bear
Baby Bear
Mummy Bear
Baby Bear
This would give the users a much better idea of the actual structure they are looking at.
So far, I have tried changing the report group to group by "cstr(Fields!Id.Value) & cstr(Fields!ParentId.Value)", in order to re-establish a unique grouping, so that no records are aggregated into invisibility, but this loses the ordering where children appear immediately after their parent, so I get something like this:
Level 1 Level 2
Daddy Bear
Baby Bear
Baby Bear
Mummy Bear
I have also tried adding ROW_NUMBER() OVER (ORDER BY Id, ParentId) as a new column in the query, to group on that, unquely, but SSRS seems to have a problem with this. The final workaround I am now using is to list only the distinct values as in the first example, but use an Action in each table row to run the report again for each node, on click. This is far from ideal, however.
I have also Googled without result.
I am stuck as to what to do.
Any help would be greatly appreciated - what should I do?
Thanks for your time,
Mark
Why can't you add the ROW_NUMBER() exactly?
SELECT ROW_NUMBER() over (order by parentid) as rn, * FROM
(SELECT 0 AS ParentId, 1 AS Id, 'Daddy Bear' AS Name UNION
SELECT 0 AS ParentId, 2 AS Id, 'Mummy Bear' AS Name UNION
SELECT 1 AS ParentId, 3 AS Id, 'Baby Bear' AS Name UNION
SELECT 2 AS ParentId, 3 AS Id, 'Baby Bear' AS Name) AS FamilyMember
Produces a "unique" id per row for grouping on.
UPDATE
So based on my understanding of your problem, you want a recursive CTE. There are quite a few questions here on SO about them, so between that and that link I encourage you to figure out how to produce a dataset that fits your needs.

Excluding results from an SQL search based on the contents of another column

The table I'm using has 3 important columns on which to exclude entries in a table. I'll call them:
SampleTable:
Thing_Type (varchar)
Thing_ID (int)
Parent_ID (int)
I want to find all 'leaf' entries of a specific type. However, it is possible that an entry of that type has a child that is not of that type, and thus I don't want to exclude it without first filtering the table to only that type. Then I want to include all entries which have an ID that is not present anywhere in the ParentID column.
There's no EXISTS in the tool I'm using (not that I'm sure it would help).
Ignoring the fact that the tool I'm using doesn't like the following, and that it might not be syntactically correct, here's what I feel it should be like.
SELECT * FROM (
SELECT *
FROM SampleTable
WHERE SampleTable.Thing_Type = 'DesiredType'
)
WHERE Thing_ID NOT IN Parent_ID
I'm pretty sure this is wrong but I'm not sure how to make it right.
First, NOT IN has to go against a set, not a single value, so NOT IN parent_id doesn't actually make sense. This is one way to approach this problem:
SELECT
thing_type,
thing_id,
parent_id
FROM
Sample_Table T1
WHERE
thing_type = 'Desired Type' AND
thing_id NOT IN (
SELECT parent_id
FROM Sample_Table T2
WHERE T2.thing_type = 'Desired Type'
)

Normalizing a table, from one to the other

I'm trying to normalize a mysql database....
I currently have a table that contains 11 columns for "categories". The first column is a user_id and the other 10 are category_id_1 - category_id_10. Some rows may only contain a category_id up to category_id_1 and the rest might be NULL.
I then have a table that has 2 columns, user_id and category_id...
What is the best way to transfer all of the data into separate rows in table 2 without adding a row for columns that are NULL in table 1?
thanks!
You can create a single query to do all the work, it just takes a bit of copy and pasting, and adjusting the column name:
INSERT INTO table2
SELECT * FROM (
SELECT user_id, category_id_1 AS category_id FROM table1
UNION ALL
SELECT user_id, category_id_2 FROM table1
UNION ALL
SELECT user_id, category_id_3 FROM table1
) AS T
WHERE category_id IS NOT NULL;
Since you only have to do this 10 times, and you can throw the code away when you are finished, I would think that this is the easiest way.
One table for users:
users(id, name, username, etc)
One for categories:
categories(id, category_name)
One to link the two, including any extra information you might want on that join.
categories_users(user_id, category_id)
-- or with extra information --
categories_users(user_id, category_id, date_created, notes)
To transfer the data across to the link table would be a case of writing a series of SQL INSERT statements. There's probably some awesome way to do it in one go, but since there's only 11 categories, just copy-and-paste IMO:
INSERT INTO categories_users
SELECT user_id, 1
FROM old_categories
WHERE category_1 IS NOT NULL