Оператор SQL SELECT From two tables (friendship)

#c# #asp.net #sql #sql-server

#c# #asp.net #sql #sql-сервер

Вопрос:

У меня есть следующие созданные таблицы:

Таблица # 1: tbl_Connections

 USE [taaraf_db]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[tbl_Connections](
    [uc_Id] [int] IDENTITY(1,1) NOT NULL,
    [uc_User] [nvarchar](50) NOT NULL,
    [uc_Connection] [nvarchar](50) NOT NULL,
    [uc_IsPending] [int] NOT NULL,
    [uc_DateTime] [datetime] NOT NULL,
 CONSTRAINT [PK_tbl_Connections] PRIMARY KEY CLUSTERED 
(
    [uc_Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[tbl_Connections] ADD  CONSTRAINT [DF_tbl_Connections_uc_IsPending]  DEFAULT ((1)) FOR [uc_IsPending]
GO
 

Таблица №2: tbl_LiveStream

 USE [taaraf_db]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[tbl_LiveStreams](
    [ls_Id] [int] IDENTITY(1,1) NOT NULL,
    [ls_Story] [nvarchar](max) NOT NULL,
    [ls_User] [nvarchar](50) NOT NULL,
    [ls_Connection] [nvarchar](50) NOT NULL,
    [ls_DateTime] [datetime] NOT NULL,
 CONSTRAINT [PK_tbl_LiveStreams] PRIMARY KEY CLUSTERED 
(
    [ls_Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
 

Теперь uc_User в tbl_Connections представляет пользователя, который инициировал запрос на добавление в друзья, а uc_Connection
представляет другую сторону.
Та же концепция применяется и ко второй таблице (tbl_LiveStreams).

Я пытаюсь выбрать все новые прямые трансляции для пользователя cetrain, прямая трансляция должна быть получена для определенного пользователя, только если этот пользователь подключен к другой стороне (uc_IsPending = 0)

У меня есть функция C #, которая принимает следующие аргументы:

 public static DataTable GetAsyncLiveStream(string CurrentUser, int startAt, int howMany) { ... }
 

И с учетом вышесказанного, DataTable должен возвращать все новые элементы в прямом эфире для данного CurrentUser (ls_User), если указанные выше требования верны.

Это что-то вроде ленты новостей Facebook, того, что происходит с друзьями и так далее… Ах да, tbl_LiveStream заполняется всякий раз, когда кто-то (ls_User) инициирует какое-то конкретное событие для (ls_Connection).

Я не уверен, не усложняю ли я здесь свою жизнь, но это то, что у меня есть, и я ценю любую помощь.

Я должен упомянуть, что я сделал это, перебрав все возвращенные записи из tbl_LiveStream и выполнив некоторую проверку с помощью функции пользовательского класса.IsFriends(), который проверяет статус дружбы в базе данных и программно заполняет таблицу данных… Что в некотором роде глупо, я признаю. Но я не уверен, как это сделать.

И последнее, я использую следующий запрос для возврата ограниченных результатов:

 SELECT * FROM (
SELECT row_number() OVER (ORDER BY ) AS rownum, ls_Id
FROM )
AS A
WHERE A.rownum BETWEEN (@start) AND (@start   @rowsperpage) 
 

Пожалуйста, помогите и спасибо за ваше время.

РЕДАКТИРОВАТЬ Я хотел бы отметить, что именно так я выбираю, кто с кем дружит, из таблицы tbl_Connections.

     const string sql = "SELECT REPLACE((uc_Connection   uc_User), @CurrentUser, '') AS Connection "  
                       "FROM tbl_Connections Connection "  
                       "WHERE (@CurrentUser = uc_Connection) OR (@CurrentUser = uc_User)";
 

Комментарии:

1. Вы должны определить для этого представление, которое использует ваш row_number() запрос-оболочка. Что у вас есть на данный момент?

2. У меня есть то, что я опубликовал выше… На этом пока все. Я действительно не знаю, с чего начать.

3. Можете ли вы изменить базу данных? Каковы ваши фактические требования (если у вас есть две разные таблицы с [фактически] одинаковой структурой, у вас, вероятно, есть таблица для извлечения)? Вы должны использовать подготовленные операторы, а не объединенные строки, если вы этого еще не сделали (SQL-инъекция). Имена таблиц не должны иметь префикса с tbl (бессмысленно, если все имеет префикс), а столбцы не должны иметь префикса с сокращенными именами таблиц (сбивающие с толку, бессмысленные при выборе только из одной таблицы, и вы все равно хотите использовать псевдоним при выборе из нескольких таблиц).

Ответ №1:

 SELECT * FROM (
SELECT row_number() OVER (ORDER BY ) AS rownum, ls_Id
FROM )
AS A
WHERE A.rownum BETWEEN (@start) AND (@start   @rowsperpage) 
 

Этот синтаксис неверен. Вы не можете сделать это так. Используйте объединение или используйте LINQ to SQL.

С точки зрения критики, не получайте таблицы данных, получайте сущности. Похоже, вы здесь немного усложняете, используя технологии, с которыми вы, возможно, не знакомы. Я бы посоветовал взять все существующие в настоящее время данные и поместить их в файл CSV, а затем запустить приложение с нуля с помощью чего-то вроде Sharp Architecture, которое может абстрагироваться от некоторых из этих деталей для вас.