sqlite view only produces one result when it should produce many - sqlite

I have a table squitters which is full of aircraft transmissions. My view called active, returns a list of unique identifiers (hex_ident) and puts them in column d_active_hex. From this view I want to join it with my table and return the most recent transmission that contains lat,lon,alt data for each active hex_ident. My active view is working properly, but my second view is only returning one entry when I know there should be multiple, up to and including but not necessarily the number of active hex_idents. Here's the request.
cur.execute("""
CREATE VIEW IF NOT EXISTS activepos AS
SELECT hex_ident,max(parsed_time),lat,lon,altitude
FROM squitters JOIN active
ON squitters.hex_ident = active.d_hex_ident AND transmission_type = 3;
""")
I'm currently adding the results of my view called active to a list in python and then looping through the list and making a separate request for each list item like this
SELECT hex_ident,max(parsed_time),lat,lon,altitude
FROM squitters
WHERE hex_ident = ? AND transmission_type = 3
which produces the expected result but that seems inefficient and I'd rather simplify my code and learn how to do it in sql at the same time. Messing around with it, it seems like the max(parsed_time) is the issue because it's selecting the latest transmission out of every transmission, not the latest for each hex_ident but not sure how to achieve what I want.
Any ideas?

I suspect that you want to group by hex_ident:
CREATE VIEW IF NOT EXISTS activepos AS
SELECT s.hex_ident, MAX(parsed_time) parsed_time, lat, lon, altitude
FROM squitters s JOIN active a
ON s.hex_ident = a.d_hex_ident
WHERE transmission_type = 3
GROUP BY s.hex_ident
Also you should qualify all the column names with the table name/alias that contain them. In my code I left unqualified all the columns that I couldn't identify the table's alias.

Related

Moving rows in sqlite database

I have a table that is actually a ranking list. I want to give user a chance to rearrange that top the way he wants, ergo, allow him to move the rows in that table. Should I create a separate column that would hold the place, or can it be done using embedded order in table?
The documentation says:
If a SELECT statement that returns more than one row does not have an ORDER BY clause, the order in which the rows are returned is undefined.
(This is true for all SQL databases.)
So you cannot rely on the order that the rows happen to be stored in; you have to use some value in some table column.

Multiple inserts using 'User Defined Table Type' (asp.net sql-server)

In my ASP.NET web app I have a DataTable filled with data to insert into tblChildren.
The DataTable is passed to a stored procedure.
In the SP I need to read each row (e.i Loop through the DataTable), change a couple of columns in it (with accordance to the relevant data in tblParents) and only then insert the row into tblChildren.
SqlBulkCopy wouldn't do and I don't think TVP will do either (not sure... not too familiar with it yet).
Of course I can iterate through the DataTable rows in the app and send each one separately to the SP, but that would mean hundreds of round trips to the SqlServer.
I came across two possibilities that might achieve that : (1) Temp table
(2) Cursor.
The first is quite messy and the second, as I understand it, is NOT recommended)
Any guidance would be much appreciated.
EDIT :
I tried the approach of user-defined Table Type.
That works because I populate the Table Type (TT_Children) with values in the TT_Child_Family_Id column.
In real life, though, I will not know these values and I would need to loop thru #my_TT_Children and for each row get the value from tblFamilies, something like this :
SELECT Family_Id FROM tblFamilies WHERE Family_Name = TT_Child_Last_Name
(assuming there is always an equivalent for TT_Child_Last_Name in tblFamilies.Family_Name)
So my question is - how to loop through the table-type and for each row look up a value in a different table?
EDIT 2 (the solution) :
As in Amir's perfect answer, the stored procedure should look like this :
ALTER PROCEDURE [dbo].[usp_Z_Insert_Children]
#my_TT_Children TT_Children READONLY
AS
BEGIN
INSERT INTO tblChildren(Child_FirstName,
Child_LastName,
Child_Family_ID)
SELECT Cld.tt_child_FirstName,
Cld.tt_child_LastNAme,
Fml.Family_Id FROM #my_TT_Children Cld
INNER JOIN tblFamilies fml
ON Cld.TT_Child_LastName = Fml.Family_Name
END
Notes by Amir : column Family_Name in tblFamily must be unique and preferably indexed.
(Also I noticed that in case TT_Child_LastName does not have a match in tblFamilies, the row will not be inserted and I'll never know about it. That means that I have to check somehow if all rows were successfully processed).
You can join tblFamilies into the insert in the procedure and take the value from there. Much more efficient than looping through.
Or create a cursor and do one child at a time.
1) Make sure there is only one occurance of FamilyName in tblFamilies.
2) Make sure that if tblFamilies is a large table, then the FamilyName column is indexed.
INSERT INTO tblChildren(Child_FirstName, Child_LastName, Child_Family_ID)
SELECT Cld.tt_child_FirstName,
Cld.tt_child_LastNAme,
Fml.FamilyID
FROM #my_TT_Children Cld
INNER JOIN tblFamilies fml on Cld.TT_Child_LastName = Fml.FamilyName
But be aware that if tblFamilies has more than one entry per Family_Name, then this will duplicate the data. In this case you will need to add more restrictions in the where.

Data from Multiple Data Sources in One Column in Grid

I've been thrown quite the scenario today. Essentially, I have one table (ProjTransPosting) that houses records, and that table relates to a number of similarly structured tables (ProjCostTrans, ProjRevenueTrans, etc). They relate by TransId, but each TransId will relate to only one of the number of child tables (meaning if a TransId of 137 exists in ProjCostTrans, there cannot be a TransId of 137 in ProjRevenueTrans). The schemas of the children tables are identical.
So, my original thought was to create a Map and create the mappings from the various children tables. And then I would use this Map as a datasource in the form so everything can show up in one column. I created all the relationships between the Map and the children table along with the relation to the parent table. I put Map in the form as a datasource and this caused a blank Grid, although I don't know why. Is it the case that the Map object can only by of one table type at any given time? I thought the purpose of this was that it could be universal and act as a buffer to many record types. I'd like to pursue this route as this definitely would achieve what I'm looking for.
In failing this I was forced to arrange my Data Source to perform something like this: SELECT ProjTransPosting LEFT JOIN ProjCostTrans LEFT JOIN ProjRevenueTrans ... The problem with this is, each child table I add-on, it's creating additional columns, and the values of the other columns are all NULL (blank in AX). So I have something like this:
Parent.TransId ChildA.Field ChildB.Field ChildC.Field
1 NULL 1256 NULL
2 1395 NULL NULL
3 NULL 4762 NULL
4 NULL NULL 1256
Normally, the user would deal with the annoyance of having the extra columns show up, but they want to also be able to filter on the fields in all the children tables. My example above, they want to be able to filter "1256" and the results would return TransIds 1 and 4, but obviously since the values in this case are spread out in multiple columns, this cannot be done by the user.
Ideally the Map would "combine" these columns into one and then the user could filter easily on it. Any ideas on how to proceed with this?
Try creating a union query and then a view based on that query.
Maps are supposed to be used only in X++, and not as data sources in forms.
This sounds like the exact purpose of table inheritance in AX 2012.
http://msdn.microsoft.com/en-us/library/gg881053.aspx
When to use:
http://msdn.microsoft.com/en-us/library/gg843731.aspx
EDIT: Adding my comments here to make this a more full answer.
Let's say you have three tables TabPet, TabPetCat, TabPetDog, where TabPet is the supertype table and the others are decedents.
If you insert two records each into TabPetCat and TabPetDog (4 total), they will all have unique recIds. Let's say TabPetCat gets 5637144580 and 5637144581. TabPetDog gets 5637144582, and 5637144583.
If you open TabPet, you will see 5637144580, 5637144581, 5637144582, and 5637144583.
So what you would do is make your table ProjTransPosting the supertype and then ProjCostTrans, ProjRevenueTrans, etc descendant tables. Unless transId is really necessary, you could just get rid of it and only use RecId.

Query one for column headers, query 2 for row data

I would like to know how to use asp.net vb to create a gridview that has one query be the column headers then use those column headers to populate the table. I have accomplished this in asp classic but would like to know how to to it in .net. The following are my queries that accomplish this in asp classic.
Select DOA,GroupName From Groups Where Doa is not null Order by zDOA
I use that query to populate the top of my table, then use this to get the users and their groups.
SELECT DISTINCT TM.PersonID, GroupMembers.FullNm, TM.zUpdatedOn, Location.LocationName FROM GroupMembers INNER JOIN TM ON GroupMembers.PersonID = TM.PersonID Inner JOin Location ON Location.LocationID = GroupMembers.LocationID INNER JOIN Groups ON GroupMembers.GroupsID= Groups.ID WHERE (GroupMembers.zIsActive = 1) AND GroupMembers.LocationID = "&LocationID&" AND Groups.DOA IS NOT NULL order by FullNm
That query gets people's name, their location(from StringQuery) and then finds out which groups they are in. When it cycles through which groups they are in, it compares their groups to all of the groups. When they match I put a check box in the correct spot. I have attached a image of this. The RED is from the first Query and the BLUE is from the second query. My question is how to replicate this in .net. I am unable to put the first query as the columns and fill in the rest with the second query.
![Example]
The answer is to use the sql pivot function. http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query

ASP.NET / SQL drop-down list sort order

I am trying to correct the sort order of my ASP.NET drop down list.
The problem I have is that I need to select a distinct Serial number and have these numbers organised by DateTime Desc.
However I cannot ORDER BY DateTime if using DISTINCT without selecting the DateTime field in my query.
However if I select DateTime this selects every data value associated with a single Serial number and results in duplications.
The purpose of my page is to display data for ALL Serials, or data associated to one serial. When a new cycle begins (because it is a new production run) the Serial reverts to 1. So I cannot simply organise by serial number either.
When I use the following SQL statement the list box is in the order I require but after a period of time (usually a few hours) the order changes and appears to have no organised structure.
alt text http://img7.imageshack.us/i/captureky.jpg/
I'm fairly new to ASP.NET / SQL, does anyone know of a solution to my problem.
If you have multiple date times for each serial number, then which do you want to use for ordering? If the most recent, try this:
SELECT SerialNumber,
MAX(DateTimeField)
FROM Table
GROUP BY SerialNumber
ORDER BY 2 DESC
I don´t know if everybody agrees with that, but when I see a DISTINCT in a query the first thought that goes trough my mind is "This is wrong". Generally, DISTINCT is not necessary and it´s used when the person writing the query doesnt know very well what he is doing and this might be the case since you said you are new with Sql.
Without complete knowledge of your model is difficult to assist you a hundred percente, but I would say that you should use a GROUP BY clause instead of DISTINCT, then you can order it correctly.

Resources