Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
К примеру есть запрос к таблица, который вернёт таблицу с именем продукта, цену, категорию, и кол-во.
SELECT Products.Name, 
	   Products.Price, 
	   Categories.Name AS 'Category Name', 
	   Orders.Quentity
FROM Products 
INNER JOIN Categories ON Categories.ID = Products.CategoryID 
LEFT JOIN Orders ON Orders.ProductID = Products.ID


Например наименование товара будет какой-нибудь ноутбук, цена одинаковая, категория соответственно то же, отличаеться только колонна с кол-вом данного предмета
Как например вернуть данные в формате что бы столбцы которые повторялись остались такими же, а значения которые отличаются, выводились разные.
Pruduct name price category quentity
g500 350 laptop 5
___10

Да же не знаю как сформулировать правильно вопрос.
15 апр 16, 11:23    [19060736]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
unsafe,

с вопросом и впрямь беда
15 апр 16, 11:28    [19060781]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21101
Показанный запрос не может вернуть показанный результат.
15 апр 16, 11:28    [19060785]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21101
Если же речь об обратной задаче - то эту заботу (сокрытие части значений) следует поручить клиенту.
15 апр 16, 11:29    [19060794]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
На c# Отображение сущностей выглядит следующем образом:
    
    class Product
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int CategoryID { get; set; }

        public Category Category { get; set; }
        public List<Order> Order { get; set; }
    }

    class Order
    {
        public int ID { get; set; }
        public int Quentity { get; set; }
        public int ProductID { get; set; }
        public int ClientCompanyID { get; set; }
    }

    public class Category
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int ParentID { get; set; }
    }

И необходимо одним запросом заджойнить, таблицы, и соответственно повторяющиеся значения из таблицы Orders будут записаны в список.
15 апр 16, 11:29    [19060797]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
Ну уже и функцию выложу
[/SRC][src]public IEnumerable<Product> GetProductJoinCategogiesAndOrders()
        {
            using (SqlConnection myConnection = new SqlConnection(connection.ConnectionString))
            {
                myConnection.Open();
                string strSQL = "SELECT DISTINCT Products.Name, " +
                                       "Products.Price, " +
                                       "Categories.Name AS 'CategoryName', " +
                                       "Orders.Quentity, " +
                                       "Orders.ID " +
                                "FROM Products " +
                                "INNER JOIN Categories ON Categories.ID = Products.CategoryID " +
                                "LEFT JOIN Orders ON Orders.ProductID = Products.ID ";

                using (SqlCommand myCommand = new SqlCommand(strSQL, myConnection))
                {
                    using (SqlDataReader reader = myCommand.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Product p = new Product();
                            p.Category = new Category();
                            p.Order = new List<Order>();

                            p.Name = reader.IsDBNull(1) ? "Product without name" : Convert.ToString(reader["Name"]);
                            p.Price = Convert.ToDecimal(reader["Price"]);
                            p.Category.Name = reader.IsDBNull(3) ? "Category without name" : Convert.ToString(reader["CategoryName"]);

                            Order o = new Order();
                            o.ID = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader["ID"]);
                            o.Quentity = reader.IsDBNull(3) ? 0 : Convert.ToInt32(reader["Quentity"]);

                            p.Order.Add(o);

                            yield return p;
                        }
                    }
                }
            }
        }
15 апр 16, 11:32    [19060825]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
unsafe,

есть мнение, что решать вопросы клиента на c# надо в соответствующей ветке :)
15 апр 16, 11:34    [19060838]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
TaPaK, Я скорее думал, что у меня с SQL что то не то, сейчас вот доходит, что с запросом всё нормально, вот только не знаю как записать это правильно в свои сущности. Где то иф поставить что ли...
15 апр 16, 11:36    [19060849]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
unsafe,

вообщем-то вопрос по прежнему не ясен :) затерть повторяющиеся столбцы? сортировку менять будут? :)
15 апр 16, 11:39    [19060881]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
Konst_One
Member

Откуда:
Сообщений: 11600
сделайте сначала выборку без Orders. потом в цикле по ProductID отберите привязанные ордеры:

select * from Orders where ProducID  = @ProductID


а ещё лучше используйте linq2sql + ef им сразу весь массив получайте как вам надо
15 апр 16, 11:41    [19060893]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
Konst_One, linq и ef нам пока запретили. то есть надо на чистом ado. Вот сижу ломаю голову, как это всё организовать, одним запросом
15 апр 16, 11:47    [19060962]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
iljy
Member

Откуда:
Сообщений: 8711
unsafe,

ну т.е. это тестовое задание? Тогда его надо решать самостоятельно. А поможет вам ROW_NUMBER() OVER(PARTITION BY групповые столбцы ORDER BY не важно что).
15 апр 16, 11:59    [19061078]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
_djХомяГ
Guest
Один из вариантов ....
declare @tmp table (name varchar(10),price int,category varchar(10),quan int)
insert into @tmp 
select 'g500',350,'laptop',5
union all 
select 'g500',350,'laptop',10
union all 
select 'g500',350,'bbb',10
union all
select 'g500',350,'bbb',10


;with cte 
as
(
  select name,price,category,min(quan) as quan,row_number() over (order by name,price,category) as GR 
  from @tmp 
  group by name,price,category
  union all
  select null,null,null,t.quan,cte.gr from @tmp t 
  join cte on cte.name=t.name and cte.price=t.price and cte.category=t.category and cte.quan<>t.quan

)
select name,price,category,quan from cte order by gr,quan   option (maxrecursion 0)
15 апр 16, 12:15    [19061223]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4832
unsafe
Как например вернуть данные в формате что бы столбцы которые повторялись остались такими же, а значения которые отличаются, выводились разные.


Смотрите в сторону функций LAG и LEAD
15 апр 16, 15:59    [19063095]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
a_voronin
unsafe
Как например вернуть данные в формате что бы столбцы которые повторялись остались такими же, а значения которые отличаются, выводились разные.


Смотрите в сторону функций LAG и LEAD

если версия сервера позволяет
15 апр 16, 16:04    [19063130]     Ответить | Цитировать Сообщить модератору
 Re: JOIN таблицы с удалением повторений  [new]
unsafe
Member

Откуда:
Сообщений: 55
Оставлю здесь, то как я решил проблему.
Пускаем цикл, для проверки если уже такая созданная запись. Если есть, то соответсвенно данные из таблицы Orders добавляем в существующую запись в список.
Более точная постановка вопроса скорее была бы, имплементация отношения один-ко-многим на c#.
public List<Product> GetProductJoinCategogiesAndOrders()
        {
            using (SqlConnection myConnection = new SqlConnection(connection.ConnectionString))
            {
                myConnection.Open();
                string strSQL = "SELECT Products.ID AS ProductID, " +
                                       "Products.Name AS ProductName, " +
                                       "Products.Price, " +
                                       "Orders.ID AS OrderID, " +
                                       "Orders.Quentity, " +
                                       "Categories.Name AS CategoryName " +
                                "FROM Products " +
                                "INNER JOIN Categories ON Categories.ID = Products.CategoryID " +
                                "LEFT JOIN Orders ON Orders.ProductID = Products.ID ";

                using (SqlCommand myCommand = new SqlCommand(strSQL, myConnection))
                {
                    using (SqlDataReader reader = myCommand.ExecuteReader(System.Data.CommandBehavior.CloseConnection))
                    {
                        List<Product> products = new List<Product>();

                        while (reader.Read())
                        {
                            Product p = new Product();
                            p.ID = Convert.ToInt32(reader["ProductID"]);
                            p.Name = reader.IsDBNull(1) ? "Product without name" : Convert.ToString(reader["ProductName"]);
                            p.Price = Convert.ToDecimal(reader["Price"]);

                            p.Category = new Category();
                            p.Category.Name = reader.IsDBNull(5) ? "Category without name" : Convert.ToString(reader["CategoryName"]);

                            Order o = new Order();
                            o.ID = reader.IsDBNull(3) ? 0 : Convert.ToInt32(reader["OrderID"]);
                            o.Quentity = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader["Quentity"]);
                            
                            // check if exist product   
                            Product existingProduct = null;
                            foreach (Product item in products)
                                if(item.ID == p.ID) // ID is Primary KEY, and is perfect for check
                                    existingProduct = item;

                            if (existingProduct != null)
                            {// product exist
                                existingProduct.Order.Add(o);
                            }
                            else
                            {
                                p.Order = new List<Order>();
                                p.Order.Add(o);
                                products.Add(p);
                            }
                        }

                        return products;
                    }
                }
            }
        }
16 апр 16, 23:11    [19067573]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить